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 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 as well as Android `.xml` 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, 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
@@ -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 iOS and Android string files to ship with our products.'
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 ''
@@ -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
- value = value.gsub('"', '\\\\"')
103
+ if value
104
+ value = value.gsub('"', '\\\\"')
104
105
 
105
- comment = row.comment
106
- if comment
107
- comment = comment.gsub('*/', '* /')
108
- end
106
+ comment = row.comment
107
+ if comment
108
+ comment = comment.gsub('*/', '* /')
109
+ end
109
110
 
110
- if comment && comment.length > 0
111
- f.print "/* #{comment} */\n"
112
- end
111
+ if comment && comment.length > 0
112
+ f.print "/* #{comment} */\n"
113
+ end
113
114
 
114
- f.print "\"#{key}\" = \"#{value}\";\n"
115
- end
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
@@ -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|
@@ -1,3 +1,3 @@
1
1
  module Twine
2
- VERSION = '0.2.2'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,12 @@
1
+ /**
2
+ * JQuery Language File
3
+ * Generated by Twine
4
+ * Language: en
5
+ */
6
+ {
7
+
8
+ /* My Strings */
9
+ "key1":"key1-english",
10
+ "key3":"key3-english",
11
+ "key5":"A new string"
12
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * JQuery Language File
3
+ * Generated by Twine
4
+ * Language: en
5
+ */
6
+ {
7
+
8
+ /* My Strings */
9
+ "key1":"key1-english",
10
+ "key3":"key3-english"
11
+ }
@@ -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.2.2
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-04-16 00:00:00.000000000 Z
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 \n It is geared toward Mac OS X, iOS, and Android developers.\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.18
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.