twine 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +14 -1
- data/lib/twine/cli.rb +4 -1
- data/lib/twine/formatters.rb +3 -1
- data/lib/twine/formatters/abstract.rb +5 -1
- data/lib/twine/formatters/android.rb +1 -4
- data/lib/twine/formatters/flash.rb +110 -0
- data/lib/twine/formatters/gettext.rb +100 -0
- data/lib/twine/version.rb +1 -1
- data/test/fixtures/en-1.po +16 -0
- data/test/fixtures/strings-3.txt +5 -0
- data/test/fixtures/test-output-7.txt +14 -0
- data/test/fixtures/test-output-8.txt +9 -0
- data/test/twine_test.rb +25 -1
- metadata +17 -15
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9c61dcacafc740f0edf24674f331c77c83b1d94b
|
4
|
+
data.tar.gz: e45d63d180e8d396194d1f86d408acefb6813886
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05f6f055d5eb781de1173a0556921e286381a0effbe328a8be5d586405fc10b0a25fc2e1c235f58a9ddbd96264f3fd3a1f27bc965386302e9522c1806184b961
|
7
|
+
data.tar.gz: ef330b79c5c17f265823e2646b04f30e7a415cf39569148968f5708cee40c7b2108dc9de64f5facfced1d8ec35d6e7a1ed129d3677234ab38f5a6b10126cfb4f
|
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, 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.
|
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, gettext `.po` 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
|
|
@@ -74,6 +74,7 @@ Twine currently supports the following formats for outputting strings:
|
|
74
74
|
|
75
75
|
* [iOS and OS X String Resources][applestrings] (format: apple)
|
76
76
|
* [Android String Resources][androidstrings] (format: android)
|
77
|
+
* [Gettext PO Files][gettextpo] (format: gettext)
|
77
78
|
* [jquery-localize Language Files][jquerylocalize] (format: jquery)
|
78
79
|
|
79
80
|
If you would like to enable twine to create language files in another format, create an appropriate formatter in `lib/twine/formatters`.
|
@@ -156,9 +157,21 @@ It is easy to incorporate Twine right into your iOS and OS X app build processes
|
|
156
157
|
|
157
158
|
Now, whenever you build your application, Xcode will automatically invoke Twine to make sure that your `.strings` files are up-to-date.
|
158
159
|
|
160
|
+
## Contributors
|
161
|
+
|
162
|
+
Many thanks to all of the contributors to the Twine project, including:
|
163
|
+
|
164
|
+
* [Ishitoya Kentaro](https://github.com/kent013)
|
165
|
+
* [Kevin Everets](https://github.com/keverets)
|
166
|
+
* [Kevin Wood](https://github.com/kwood)
|
167
|
+
* [Mohammad Hejazi](https://github.com/MohammadHejazi)
|
168
|
+
* [Robert Guo](http://www.robertguo.me/)
|
169
|
+
|
170
|
+
|
159
171
|
[rubyzip]: http://rubygems.org/gems/rubyzip
|
160
172
|
[git]: http://git-scm.org/
|
161
173
|
[INI]: http://en.wikipedia.org/wiki/INI_file
|
162
174
|
[applestrings]: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
|
163
175
|
[androidstrings]: http://developer.android.com/guide/topics/resources/string-resource.html
|
176
|
+
[gettextpo]: http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html
|
164
177
|
[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 formatted string files to ship with your products. Twine currently supports iOS, OS X, Android, and jquery-localize string files.'
|
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, gettext, and jquery-localize string files.'
|
19
19
|
opts.separator ''
|
20
20
|
opts.separator 'Commands:'
|
21
21
|
opts.separator ''
|
@@ -64,6 +64,9 @@ module Twine
|
|
64
64
|
opts.on('-o', '--output-file OUTPUT_FILE', 'Write the new strings database to this file instead of replacing the original file. This flag is only useful when running the consume-string-file or consume-loc-drop commands.') do |o|
|
65
65
|
@options[:output_path] = o
|
66
66
|
end
|
67
|
+
opts.on('-n', '--file-name FILE_NAME', 'When running the generate-all-string-files command, this flag may be used to overwrite the default file name of the format.') do |n|
|
68
|
+
@options[:file_name] = n
|
69
|
+
end
|
67
70
|
opts.on('-d', '--developer-language LANG', 'When writing the strings data file, set the specified language as the "developer language". In practice, this just means that this language will appear first in the strings data file.') do |d|
|
68
71
|
@options[:developer_language] = d
|
69
72
|
end
|
data/lib/twine/formatters.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'twine/formatters/abstract'
|
2
2
|
require 'twine/formatters/android'
|
3
3
|
require 'twine/formatters/apple'
|
4
|
+
require 'twine/formatters/flash'
|
5
|
+
require 'twine/formatters/gettext'
|
4
6
|
require 'twine/formatters/jquery'
|
5
7
|
|
6
8
|
module Twine
|
7
9
|
module Formatters
|
8
|
-
FORMATTERS = [Formatters::Apple, Formatters::Android, Formatters::JQuery]
|
10
|
+
FORMATTERS = [Formatters::Apple, Formatters::Android, Formatters::Gettext, Formatters::JQuery, Formatters::Flash]
|
9
11
|
end
|
10
12
|
end
|
@@ -57,6 +57,9 @@ module Twine
|
|
57
57
|
# 1) use "s" instead of "@" for substituting strings
|
58
58
|
str.gsub!(/%([0-9\$]*)@/, '%\1s')
|
59
59
|
|
60
|
+
# 1a) escape strings that begin with a lone "@"
|
61
|
+
str.sub!(/^@ /, '\\@ ')
|
62
|
+
|
60
63
|
# 2) if there is more than one substitution in a string, make sure they are numbered
|
61
64
|
substituteCount = 0
|
62
65
|
startFound = false
|
@@ -148,10 +151,11 @@ module Twine
|
|
148
151
|
raise Twine::Error.new("Directory does not exist: #{path}")
|
149
152
|
end
|
150
153
|
|
154
|
+
file_name = @options[:file_name] || default_file_name
|
151
155
|
Dir.foreach(path) do |item|
|
152
156
|
lang = determine_language_given_path(item)
|
153
157
|
if lang
|
154
|
-
write_file(File.join(path, item,
|
158
|
+
write_file(File.join(path, item, file_name), lang)
|
155
159
|
end
|
156
160
|
end
|
157
161
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require '
|
2
|
+
require 'cgi'
|
3
3
|
require 'rexml/document'
|
4
4
|
|
5
5
|
module Twine
|
@@ -74,9 +74,6 @@ module Twine
|
|
74
74
|
else
|
75
75
|
value = ""
|
76
76
|
end
|
77
|
-
if @options[:tags]
|
78
|
-
set_tags_for_key(key, @options[:tags])
|
79
|
-
end
|
80
77
|
set_translation_for_key(key, lang, value)
|
81
78
|
if comment and comment.length > 0 and !comment.start_with?("SECTION:")
|
82
79
|
set_comment_for_key(key, comment)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Twine
|
2
|
+
module Formatters
|
3
|
+
class Flash < Abstract
|
4
|
+
FORMAT_NAME = 'flash'
|
5
|
+
EXTENSION = '.properties'
|
6
|
+
DEFAULT_FILE_NAME = 'resources.properties'
|
7
|
+
|
8
|
+
def self.can_handle_directory?(path)
|
9
|
+
return false
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_file_name
|
13
|
+
return DEFAULT_FILE_NAME
|
14
|
+
end
|
15
|
+
|
16
|
+
def determine_language_given_path(path)
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
def read_file(path, lang)
|
21
|
+
encoding = Twine::Encoding.encoding_for_path(path)
|
22
|
+
sep = nil
|
23
|
+
if !encoding.respond_to?(:encode)
|
24
|
+
# This code is not necessary in 1.9.3 and does not work as it did in 1.8.7.
|
25
|
+
if encoding.end_with? 'LE'
|
26
|
+
sep = "\x0a\x00"
|
27
|
+
elsif encoding.end_with? 'BE'
|
28
|
+
sep = "\x00\x0a"
|
29
|
+
else
|
30
|
+
sep = "\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if encoding.index('UTF-16')
|
35
|
+
mode = "rb:#{encoding}"
|
36
|
+
else
|
37
|
+
mode = "r:#{encoding}"
|
38
|
+
end
|
39
|
+
|
40
|
+
File.open(path, mode) do |f|
|
41
|
+
last_comment = nil
|
42
|
+
while line = (sep) ? f.gets(sep) : f.gets
|
43
|
+
if encoding.index('UTF-16')
|
44
|
+
if line.respond_to? :encode!
|
45
|
+
line.encode!('UTF-8')
|
46
|
+
else
|
47
|
+
require 'iconv'
|
48
|
+
line = Iconv.iconv('UTF-8', encoding, line).join
|
49
|
+
end
|
50
|
+
end
|
51
|
+
match = /((?:[^"\\]|\\.)+)\s*=\s*((?:[^"\\]|\\.)*)/.match(line)
|
52
|
+
if match
|
53
|
+
key = match[1]
|
54
|
+
value = match[2]
|
55
|
+
value.gsub!(/\{[0-9]\}/, '%@')
|
56
|
+
set_translation_for_key(key, lang, value)
|
57
|
+
if last_comment
|
58
|
+
set_comment_for_key(key, last_comment)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if @options[:consume_comments]
|
62
|
+
match = /#(.*)/.match(line)
|
63
|
+
if match
|
64
|
+
last_comment = match[1]
|
65
|
+
else
|
66
|
+
last_comment = nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def write_file(path, lang)
|
74
|
+
default_lang = @strings.language_codes[0]
|
75
|
+
encoding = @options[:output_encoding] || 'UTF-8'
|
76
|
+
File.open(path, "w:#{encoding}") do |f|
|
77
|
+
f.puts "## Flash Strings File\n## Generated by Twine #{Twine::VERSION}\n## Language: #{lang}\n"
|
78
|
+
@strings.sections.each do |section|
|
79
|
+
printed_section = false
|
80
|
+
section.rows.each do |row|
|
81
|
+
if row.matches_tags?(@options[:tags], @options[:untagged])
|
82
|
+
f.puts ''
|
83
|
+
if !printed_section
|
84
|
+
if section.name && section.name.length > 0
|
85
|
+
f.print "## #{section.name} ##\n\n"
|
86
|
+
end
|
87
|
+
printed_section = true
|
88
|
+
end
|
89
|
+
|
90
|
+
key = row.key
|
91
|
+
value = row.translated_string_for_lang(lang, default_lang)
|
92
|
+
if value
|
93
|
+
placeHolderNumber = -1
|
94
|
+
value = value.gsub(/%[d@]/) { placeHolderNumber += 1; '{%d}' % placeHolderNumber }
|
95
|
+
|
96
|
+
comment = row.comment
|
97
|
+
if comment && comment.length > 0
|
98
|
+
f.print "# #{comment}\n"
|
99
|
+
end
|
100
|
+
|
101
|
+
f.print "#{key}=#{value}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Twine
|
2
|
+
module Formatters
|
3
|
+
class Gettext < Abstract
|
4
|
+
FORMAT_NAME = 'gettext'
|
5
|
+
EXTENSION = '.po'
|
6
|
+
DEFAULT_FILE_NAME = 'strings.po'
|
7
|
+
|
8
|
+
def self.can_handle_directory?(path)
|
9
|
+
Dir.entries(path).any? { |item| /^.+\.po$/.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 = /(..)\.po$/.match(segment)
|
20
|
+
if match
|
21
|
+
return match[1]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_file(path, lang)
|
29
|
+
comment_regex = /#.? *"(.*)"$/
|
30
|
+
key_regex = /msgctxt *"(.*)"$/
|
31
|
+
value_regex = /msgstr *"(.*)"$/m
|
32
|
+
File.open(path, 'r:UTF-8') do |f|
|
33
|
+
while item = f.gets("\n\n")
|
34
|
+
key = nil
|
35
|
+
value = nil
|
36
|
+
comment = nil
|
37
|
+
|
38
|
+
for line in item.split(/\r?\n/)
|
39
|
+
comment_match = comment_regex.match(line)
|
40
|
+
if comment_match
|
41
|
+
comment = comment_match[1]
|
42
|
+
end
|
43
|
+
key_match = key_regex.match(line)
|
44
|
+
if key_match
|
45
|
+
key = key_match[1].gsub('\\"', '"')
|
46
|
+
end
|
47
|
+
value_match = value_regex.match(line)
|
48
|
+
if value_match
|
49
|
+
value = value_match[1].gsub('\\"', '"')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
if key and key.length > 0 and value and value.length > 0
|
53
|
+
set_translation_for_key(key, lang, value)
|
54
|
+
if comment and comment.length > 0
|
55
|
+
set_comment_for_key(key, comment)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_file(path, lang)
|
63
|
+
default_lang = @strings.language_codes[0]
|
64
|
+
encoding = @options[:output_encoding] || 'UTF-8'
|
65
|
+
File.open(path, "w:#{encoding}") do |f|
|
66
|
+
f.puts "msgid \"\"\nmsgstr \"\"\n\"Language: #{lang}\\n\"\n\"X-Generator: Twine #{Twine::VERSION}\\n\"\n\n"
|
67
|
+
@strings.sections.each do |section|
|
68
|
+
printed_section = false
|
69
|
+
section.rows.each do |row|
|
70
|
+
if row.matches_tags?(@options[:tags], @options[:untagged])
|
71
|
+
basetrans = row.translated_string_for_lang(default_lang)
|
72
|
+
|
73
|
+
if basetrans
|
74
|
+
key = row.key
|
75
|
+
key = key.gsub('"', '\\\\"')
|
76
|
+
|
77
|
+
comment = row.comment
|
78
|
+
if comment
|
79
|
+
comment = comment.gsub('"', '\\\\"')
|
80
|
+
end
|
81
|
+
|
82
|
+
if comment && comment.length > 0
|
83
|
+
f.print "#. \"#{comment}\"\n"
|
84
|
+
end
|
85
|
+
|
86
|
+
f.print "msgctxt \"#{key}\"\nmsgid \"#{basetrans}\"\n"
|
87
|
+
value = row.translated_string_for_lang(lang)
|
88
|
+
if value
|
89
|
+
value = value.gsub('"', '\\\\"')
|
90
|
+
end
|
91
|
+
f.print "msgstr \"#{value}\"\n\n"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/twine/version.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
msgid ""
|
2
|
+
msgstr ""
|
3
|
+
"Language: en\n"
|
4
|
+
"X-Generator: Twine\n"
|
5
|
+
|
6
|
+
msgctxt "key1"
|
7
|
+
msgid "key1-english"
|
8
|
+
msgstr "key1-english"
|
9
|
+
|
10
|
+
msgctxt "key3"
|
11
|
+
msgid "key3-english"
|
12
|
+
msgstr ""
|
13
|
+
|
14
|
+
msgctxt "key5"
|
15
|
+
msgid "A new string"
|
16
|
+
msgstr "A new string"
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<!-- Android Strings File -->
|
3
|
+
<!-- Generated by Twine <%= Twine::VERSION %> -->
|
4
|
+
<!-- Language: en -->
|
5
|
+
<resources>
|
6
|
+
<!-- SECTION: My Strings -->
|
7
|
+
<string name="parameterized_string">The %1$s brown fox jumps over the %2$s dog %3$d times.</string>
|
8
|
+
<string name="percentage_string">This product is %d%% off.</string>
|
9
|
+
</resources>
|
data/test/twine_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'erb'
|
2
2
|
require 'rubygems'
|
3
3
|
require 'test/unit'
|
4
4
|
require 'twine'
|
@@ -36,6 +36,22 @@ class TwineTest < Test::Unit::TestCase
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def test_generate_string_file_5
|
40
|
+
Dir.mktmpdir do |dir|
|
41
|
+
output_path = File.join(dir, 'en.po')
|
42
|
+
Twine::Runner.run(%W(generate-string-file test/fixtures/strings-1.txt #{output_path} -t tag1))
|
43
|
+
assert_equal(ERB.new(File.read('test/fixtures/test-output-7.txt')).result, File.read(output_path))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_generate_string_file_6
|
48
|
+
Dir.mktmpdir do |dir|
|
49
|
+
output_path = File.join(dir, 'en.xml')
|
50
|
+
Twine::Runner.run(%W(generate-string-file test/fixtures/strings-3.txt #{output_path}))
|
51
|
+
assert_equal(ERB.new(File.read('test/fixtures/test-output-8.txt')).result, File.read(output_path))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
39
55
|
def test_consume_string_file_1
|
40
56
|
Dir.mktmpdir do |dir|
|
41
57
|
output_path = File.join(dir, 'strings.txt')
|
@@ -60,6 +76,14 @@ class TwineTest < Test::Unit::TestCase
|
|
60
76
|
end
|
61
77
|
end
|
62
78
|
|
79
|
+
def test_consume_string_file_4
|
80
|
+
Dir.mktmpdir do |dir|
|
81
|
+
output_path = File.join(dir, 'strings.txt')
|
82
|
+
Twine::Runner.run(%W(consume-string-file test/fixtures/strings-1.txt test/fixtures/en-1.po -o #{output_path} -l en -a))
|
83
|
+
assert_equal(File.read('test/fixtures/test-output-4.txt'), File.read(output_path))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
63
87
|
def test_generate_report_1
|
64
88
|
Twine::Runner.run(%w(generate-report test/fixtures/strings-1.txt))
|
65
89
|
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Sebastian Celis
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-05-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rubyzip
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,13 +34,14 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.9.2
|
46
|
-
description:
|
47
|
-
|
41
|
+
description: |2
|
42
|
+
Twine is a command line tool for managing your strings and their translations.
|
43
|
+
|
44
|
+
It is geared toward Mac OS X, iOS, and Android developers.
|
48
45
|
email: twine@mobiata.com
|
49
46
|
executables:
|
50
47
|
- twine
|
@@ -59,6 +56,8 @@ files:
|
|
59
56
|
- lib/twine/formatters/abstract.rb
|
60
57
|
- lib/twine/formatters/android.rb
|
61
58
|
- lib/twine/formatters/apple.rb
|
59
|
+
- lib/twine/formatters/flash.rb
|
60
|
+
- lib/twine/formatters/gettext.rb
|
62
61
|
- lib/twine/formatters/jquery.rb
|
63
62
|
- lib/twine/formatters.rb
|
64
63
|
- lib/twine/runner.rb
|
@@ -67,40 +66,43 @@ files:
|
|
67
66
|
- lib/twine.rb
|
68
67
|
- bin/twine
|
69
68
|
- test/fixtures/en-1.json
|
69
|
+
- test/fixtures/en-1.po
|
70
70
|
- test/fixtures/en-1.strings
|
71
71
|
- test/fixtures/fr-1.xml
|
72
72
|
- test/fixtures/strings-1.txt
|
73
73
|
- test/fixtures/strings-2.txt
|
74
|
+
- test/fixtures/strings-3.txt
|
74
75
|
- test/fixtures/test-output-1.txt
|
75
76
|
- test/fixtures/test-output-2.txt
|
76
77
|
- test/fixtures/test-output-3.txt
|
77
78
|
- test/fixtures/test-output-4.txt
|
78
79
|
- test/fixtures/test-output-5.txt
|
79
80
|
- test/fixtures/test-output-6.txt
|
81
|
+
- test/fixtures/test-output-7.txt
|
82
|
+
- test/fixtures/test-output-8.txt
|
80
83
|
- test/twine_test.rb
|
81
84
|
homepage: https://github.com/mobiata/twine
|
82
85
|
licenses: []
|
86
|
+
metadata: {}
|
83
87
|
post_install_message:
|
84
88
|
rdoc_options: []
|
85
89
|
require_paths:
|
86
90
|
- lib
|
87
91
|
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
-
none: false
|
89
92
|
requirements:
|
90
|
-
- -
|
93
|
+
- - '>='
|
91
94
|
- !ruby/object:Gem::Version
|
92
95
|
version: 1.8.7
|
93
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
-
none: false
|
95
97
|
requirements:
|
96
|
-
- -
|
98
|
+
- - '>='
|
97
99
|
- !ruby/object:Gem::Version
|
98
100
|
version: '0'
|
99
101
|
requirements: []
|
100
102
|
rubyforge_project:
|
101
|
-
rubygems_version:
|
103
|
+
rubygems_version: 2.0.0
|
102
104
|
signing_key:
|
103
|
-
specification_version:
|
105
|
+
specification_version: 4
|
104
106
|
summary: Manage strings and their translations for your iOS and Android projects.
|
105
107
|
test_files:
|
106
108
|
- test/twine_test.rb
|