twine 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 303ce6c7d8bab093ca71941fe800a657fb809ef3
4
- data.tar.gz: 429d906f86a7f7bd566ffc4eb8590f8157a000e0
3
+ metadata.gz: 0e7971931654800b4d398dd6c3d9e86b96e4f5ba
4
+ data.tar.gz: 64a1eccc6c604439e10c82bded869527b123f8db
5
5
  SHA512:
6
- metadata.gz: 5998ed4a6f39b0d09bcfd33d404239ccf2b7f6523aeae9fd36cd3af3b0c897ab589575ae91f365e77629718eba457ffaf6915d0965b12f40a097fb06cc054472
7
- data.tar.gz: 0659ce0901ebef294dd81b59a08a1467d1f7399e04d84b4e303900a10ffbbf9252234d059fa1ec143fcacbf93b3ef857708c3e00b7fe55166be83464ffafa0e5
6
+ metadata.gz: 808d4045076dfef7fcba6d26797eb05d7638fd3c2adc964c24059a20f378beb8c5d978f1598d651e1117a13a1fbdbdf102d21c767aee3a68c7eb5699fae7215a
7
+ data.tar.gz: a63755c14cbadb14c0bba2960ff178a5785280bbb72e300dba5dc449ea510c823c6e248a1b848306f7c5de532c658ef8d4f034e80347f58ec2a4525673cf1ab6
data/README.md CHANGED
@@ -78,7 +78,12 @@ Twine currently supports the following output formats:
78
78
 
79
79
  * [iOS and OS X String Resources][applestrings] (format: apple)
80
80
  * [Android String Resources][androidstrings] (format: android)
81
- * Supports [basic styling][androidstyling] with \<b\>, \<i\>, \<u\> and \<a\> links. These tags will *not* be escaped. Use [`getText()`](https://developer.android.com/reference/android/content/res/Resources.html#getText(int)) to read these strings. Also tags inside `<![CDATA[` won't be escaped. See [\#212](https://github.com/scelis/twine/issues/212) for details.
81
+ * HTML tags will be escaped by replacing `<` with `&lt`
82
+ * Tags inside `<![CDATA[` won't be escaped.
83
+ * Supports [basic styling][androidstyling] with `<b>`, `<i>`, `<u>` and `<a>` links.
84
+ * These tags will *not* be escaped if the string doesn't contain placeholders. You can reference them directly in your layouts or by using [`getText()`](https://developer.android.com/reference/android/content/res/Resources.html#getText(int)) to read them programatically.
85
+ * These tags *will* be escaped if the string contains placeholders. You can use [`getString()`](https://developer.android.com/reference/android/content/res/Resources.html#getString(int,%20java.lang.Object...)) combined with [`fromHtml`](https://developer.android.com/reference/android/text/Html.html#fromHtml(java.lang.String)) as shown in the [documentation][androidstyling] to display them.
86
+ * See [\#212](https://github.com/scelis/twine/issues/212) for details.
82
87
  * [Gettext PO Files][gettextpo] (format: gettext)
83
88
  * [jquery-localize Language Files][jquerylocalize] (format: jquery)
84
89
  * [Django PO Files][djangopo] (format: django)
@@ -211,7 +216,7 @@ Many thanks to all of the contributors to the Twine project, including:
211
216
  [rubyzip]: http://rubygems.org/gems/rubyzip
212
217
  [git]: http://git-scm.org/
213
218
  [INI]: http://en.wikipedia.org/wiki/INI_file
214
- [applestrings]: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
219
+ [applestrings]: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
215
220
  [androidstrings]: http://developer.android.com/guide/topics/resources/string-resource.html
216
221
  [androidstyling]: http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
217
222
  [gettextpo]: http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html
@@ -116,10 +116,15 @@ module Twine
116
116
  value = gsub_unless(value, "'", "\\'") { |substring| substring =~ inside_cdata }
117
117
  value = gsub_unless(value, /&/, '&amp;') { |substring| substring =~ inside_cdata || substring =~ inside_opening_anchor_tag }
118
118
 
119
- # escape opening angle brackes unless it's a supported styling tag
119
+ # if `value` contains a placeholder, escape all angle brackets
120
+ # if not, escape opening angle brackes unless it's a supported styling tag
120
121
  # https://github.com/scelis/twine/issues/212
121
122
  # https://stackoverflow.com/questions/3235131/#18199543
122
- angle_bracket = /<(?!(\/?(b|u|i|a|\!\[CDATA)))/ # matches all `<` but <b>, <u>, <i>, <a> and <![CDATA
123
+ if number_of_twine_placeholders(value) > 0
124
+ angle_bracket = /<(?!(\/?(\!\[CDATA)))/ # matches all `<` but <![CDATA
125
+ else
126
+ angle_bracket = /<(?!(\/?(b|u|i|a|\!\[CDATA)))/ # matches all `<` but <b>, <u>, <i>, <a> and <![CDATA
127
+ end
123
128
  value = gsub_unless(value, angle_bracket, '&lt;') { |substring| substring =~ inside_cdata }
124
129
 
125
130
  # escape non resource identifier @ signs (http://developer.android.com/guide/topics/resources/accessing-resources.html#ResourcesFromXml)
@@ -6,6 +6,11 @@ module Twine
6
6
  PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH = '([-+0#])?(\d+|\*)?(\.(\d+|\*))?(hh?|ll?|L|z|j|t|q)?'
7
7
  PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH = '(\d+\$)?' + PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH
8
8
  PLACEHOLDER_TYPES = '[diufFeEgGxXoscpaA]'
9
+ PLACEHOLDER_REGEX = /%#{PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH}#{PLACEHOLDER_TYPES}/
10
+
11
+ def number_of_twine_placeholders(input)
12
+ input.scan(PLACEHOLDER_REGEX).size
13
+ end
9
14
 
10
15
  def convert_twine_string_placeholder(input)
11
16
  # %@ -> %s
@@ -19,15 +24,13 @@ module Twine
19
24
  # %@ -> %s
20
25
  value = convert_twine_string_placeholder(input)
21
26
 
22
- placeholder_syntax = PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH + PLACEHOLDER_TYPES
23
- placeholder_regex = /%#{placeholder_syntax}/
24
-
25
- number_of_placeholders = value.scan(placeholder_regex).size
27
+ number_of_placeholders = number_of_twine_placeholders(input)
26
28
 
27
29
  return value if number_of_placeholders == 0
28
30
 
29
31
  # got placeholders -> need to double single percent signs
30
32
  # % -> %% (but %% -> %%, %d -> %d)
33
+ placeholder_syntax = PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH + PLACEHOLDER_TYPES
31
34
  single_percent_regex = /([^%])(%)(?!(%|#{placeholder_syntax}))/
32
35
  value.gsub! single_percent_regex, '\1%%'
33
36
 
@@ -61,8 +64,7 @@ module Twine
61
64
  def convert_placeholders_from_twine_to_flash(input)
62
65
  value = convert_twine_string_placeholder(input)
63
66
 
64
- placeholder_regex = /%#{PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH}#{PLACEHOLDER_TYPES}/
65
- value.gsub(placeholder_regex).each_with_index do |match, index|
67
+ value.gsub(PLACEHOLDER_REGEX).each_with_index do |match, index|
66
68
  "{#{index}}"
67
69
  end
68
70
  end
@@ -1,3 +1,3 @@
1
1
  module Twine
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.2'
3
3
  end
@@ -50,6 +50,10 @@ class TestAndroidFormatter < FormatterTest
50
50
  '<i>italic</i>' => '<i>italic</i>',
51
51
  '<u>underline</u>' => '<u>underline</u>',
52
52
 
53
+ '<b>%@</b>' => '&lt;b>%s&lt;/b>',
54
+ '<i>%@</i>' => '&lt;i>%s&lt;/i>',
55
+ '<u>%@</u>' => '&lt;u>%s&lt;/u>',
56
+
53
57
  '<span>inline</span>' => '&lt;span>inline&lt;/span>',
54
58
  '<p>paragraph</p>' => '&lt;p>paragraph&lt;/p>',
55
59
 
@@ -58,9 +62,10 @@ class TestAndroidFormatter < FormatterTest
58
62
  '<a href="target"></a>"out"' => '<a href="target"></a>\"out\"',
59
63
  '<a href="http://url.com?param=1&param2=3&param3=%20">link</a>' => '<a href="http://url.com?param=1&param2=3&param3=%20">link</a>',
60
64
 
61
- '<p>escaped</p><![CDATA[]]>' => '&lt;p>escaped&lt;/p><![CDATA[]]>',
62
- '<![CDATA[]]><p>escaped</p>' => '<![CDATA[]]>&lt;p>escaped&lt;/p>',
63
- '<![CDATA[<p>unescaped</p>]]>' => '<![CDATA[<p>unescaped</p>]]>',
65
+ '<p>escaped</p><![CDATA[]]>' => '&lt;p>escaped&lt;/p><![CDATA[]]>',
66
+ '<![CDATA[]]><p>escaped</p>' => '<![CDATA[]]>&lt;p>escaped&lt;/p>',
67
+ '<![CDATA[<p>unescaped</p>]]>' => '<![CDATA[<p>unescaped</p>]]>',
68
+ '<![CDATA[<p>unescaped with %@</p>]]>' => '<![CDATA[<p>unescaped with %s</p>]]>',
64
69
  '<![CDATA[]]><![CDATA[<p>unescaped</p>]]>' => '<![CDATA[]]><![CDATA[<p>unescaped</p>]]>',
65
70
 
66
71
  '<![CDATA[&]]>' => '<![CDATA[&]]>',
@@ -1,11 +1,13 @@
1
1
  require 'command_test'
2
2
 
3
3
  class TestGenerateAllLocalizationFiles < CommandTest
4
- def new_runner(create_folders, twine_file = nil)
5
- options = {}
6
- options[:output_path] = @output_dir
7
- options[:format] = 'apple'
8
- options[:create_folders] = create_folders
4
+ def new_runner(create_folders, twine_file = nil, options = {})
5
+ default_options = {}
6
+ default_options[:output_path] = @output_dir
7
+ default_options[:format] = 'apple'
8
+ default_options[:create_folders] = create_folders
9
+
10
+ options = default_options.merge options
9
11
 
10
12
  unless twine_file
11
13
  twine_file = build_twine_file 'en', 'es' do
@@ -18,6 +20,32 @@ class TestGenerateAllLocalizationFiles < CommandTest
18
20
  Twine::Runner.new(options, twine_file)
19
21
  end
20
22
 
23
+ class TestFormatterSelection < TestGenerateAllLocalizationFiles
24
+ def setup
25
+ super
26
+ Dir.mkdir File.join @output_dir, 'values-en'
27
+
28
+ # both Android and Tizen can handle folders containing `values-en`
29
+ android_formatter = prepare_mock_formatter(Twine::Formatters::Android)
30
+ tizen_formatter = prepare_mock_formatter(Twine::Formatters::Tizen, false)
31
+ end
32
+
33
+ def new_runner(options = {})
34
+ super(true, nil, options)
35
+ end
36
+
37
+ def test_returns_error_for_ambiguous_output_path
38
+ assert_raises Twine::Error do
39
+ new_runner(format: nil).generate_all_localization_files
40
+ end
41
+ end
42
+
43
+ def test_uses_specified_formatter_to_resolve_ambiguity
44
+ # implicit assert that this call doesn't raise an exception
45
+ new_runner(format: 'android').generate_all_localization_files
46
+ end
47
+ end
48
+
21
49
  class TestDoNotCreateFolders < TestGenerateAllLocalizationFiles
22
50
  def new_runner(twine_file = nil)
23
51
  super(false, twine_file)
@@ -1,8 +1,7 @@
1
1
  require 'command_test'
2
2
 
3
3
  class TestGenerateLocalizationFile < CommandTest
4
- def new_runner(language, file)
5
- options = {}
4
+ def new_runner(language, file, options = {})
6
5
  options[:output_path] = File.join(@output_dir, file) if file
7
6
  options[:languages] = language if language
8
7
 
@@ -59,6 +58,17 @@ class TestGenerateLocalizationFile < CommandTest
59
58
  end
60
59
  end
61
60
 
61
+ def test_uses_specified_formatter_to_resolve_ambiguity
62
+ # both Android and Tizen use .xml
63
+ android_formatter = prepare_mock_formatter(Twine::Formatters::Android)
64
+ android_formatter.stubs(:format_file).returns(true)
65
+ tizen_formatter = prepare_mock_formatter(Twine::Formatters::Tizen, false)
66
+ tizen_formatter.stubs(:format_file).returns(true)
67
+
68
+ # implicit assert that this call doesn't raise an exception
69
+ new_runner('fr', 'fr.xml', format: 'android').generate_localization_file
70
+ end
71
+
62
72
  def test_deducts_language_from_output_path
63
73
  random_language = KNOWN_LANGUAGES.sample
64
74
  formatter = prepare_mock_formatter Twine::Formatters::Android
metadata CHANGED
@@ -1,97 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twine
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Celis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-18 00:00:00.000000000 Z
11
+ date: 2018-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: safe_yaml
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '10.4'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '5.5'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '5.5'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: minitest-ci
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '3.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: mocha
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.1'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.1'
97
97
  description: |2
@@ -105,10 +105,13 @@ extensions: []
105
105
  extra_rdoc_files: []
106
106
  files:
107
107
  - Gemfile
108
- - README.md
109
108
  - LICENSE
109
+ - README.md
110
+ - bin/twine
111
+ - lib/twine.rb
110
112
  - lib/twine/cli.rb
111
113
  - lib/twine/encoding.rb
114
+ - lib/twine/formatters.rb
112
115
  - lib/twine/formatters/abstract.rb
113
116
  - lib/twine/formatters/android.rb
114
117
  - lib/twine/formatters/apple.rb
@@ -117,15 +120,12 @@ files:
117
120
  - lib/twine/formatters/gettext.rb
118
121
  - lib/twine/formatters/jquery.rb
119
122
  - lib/twine/formatters/tizen.rb
120
- - lib/twine/formatters.rb
121
123
  - lib/twine/output_processor.rb
122
124
  - lib/twine/placeholders.rb
123
125
  - lib/twine/plugin.rb
124
126
  - lib/twine/runner.rb
125
127
  - lib/twine/twine_file.rb
126
128
  - lib/twine/version.rb
127
- - lib/twine.rb
128
- - bin/twine
129
129
  - test/command_test.rb
130
130
  - test/fixtures/consume_localization_archive.zip
131
131
  - test/fixtures/enc_utf16be.dummy
@@ -167,17 +167,17 @@ require_paths:
167
167
  - lib
168
168
  required_ruby_version: !ruby/object:Gem::Requirement
169
169
  requirements:
170
- - - '>='
170
+ - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: '2.0'
173
173
  required_rubygems_version: !ruby/object:Gem::Requirement
174
174
  requirements:
175
- - - '>='
175
+ - - ">="
176
176
  - !ruby/object:Gem::Version
177
177
  version: '0'
178
178
  requirements: []
179
179
  rubyforge_project:
180
- rubygems_version: 2.0.14.1
180
+ rubygems_version: 2.5.2
181
181
  signing_key:
182
182
  specification_version: 4
183
183
  summary: Manage strings and their translations for your iOS, Android and other projects.