dotstrings 0.4.0 → 0.6.0

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
  SHA256:
3
- metadata.gz: e9c320ba9bef4d63af10c9c9fd3d91ad41da99b3663538f0b89ebdc6fc780d31
4
- data.tar.gz: 24e762927cd739f3475a8a550a751f808dd81d73292e47f7449c657edeaa88db
3
+ metadata.gz: 3043892fd5f3068811c63cd3da980cfef6779522359be1974dea0b3be6d4f60c
4
+ data.tar.gz: eb04dbb9ff868273b783a1f8337d4cd11098cc0450a4676beb241a0b88e49dff
5
5
  SHA512:
6
- metadata.gz: f24ad0efde29b52a33f28cd0e434970bde12556d9236c632495eebdfd089ed550e54a41f67fb844c70677c53bbdaccdbb93f593cafd535062532f062297ab7b4
7
- data.tar.gz: d61a17f762188162a431c6289b96e23d4374ca2a29a82e84b58e92bf097d79746a352418859e12c2d1dcf13c8844a53a9975360be6c0a98f65d046c16aba45cc
6
+ metadata.gz: 53c29b660b3af9ab6795080176567edc8950c4df357a86d5845b6c4166aad593812a9529d6ec2b333c8cfa1996953c7df1ece183d6ac7011eaa1517c9461eeba
7
+ data.tar.gz: bb1a56e77beae28a1a3b1fc52c47096448731db40cd81905e7cfb9652aa9836d93a2a756cf674d7679dc7e45842c70dbde59f70cf214847e167c96015a92b949
data/CHANGELOG.md CHANGED
@@ -1,29 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.6.0] - 2024-02-27
4
+
5
+ - Dropped support for Ruby 2.5.
6
+ - Small performance improvements for unicode parsing.
7
+
8
+ ## [v0.5.0] - 2022-09-24
9
+
10
+ - Added `strict` parameter to the parser to allow for more lenient parsing. This is useful in cases where we don't want the parser to raise an error when encountering multiple comments or escaped characters that don't need to be escaped.
11
+
3
12
  ## [v0.4.0] - 2022-09-18
13
+
4
14
  ### Added
5
- * Added `DotStrings::File#each`, `DotStrings::File#length`, `DotStrings::File#count`, and `DotStrings::File#empty?` methods.
6
- * Allow comparing `DotStrings::File` objects.
15
+
16
+ - Added `DotStrings::File#each`, `DotStrings::File#length`, `DotStrings::File#count`, and `DotStrings::File#empty?` methods.
17
+ - Allow comparing `DotStrings::File` objects.
7
18
 
8
19
  ## [v0.3.0] - 2022-08-07
20
+
9
21
  ### Changed
10
- * Improved unicode code point parsing and validation.
11
- * Added `DotStrings::File#sort`, `DotStrings::File#sort!`, and `DotStrings::File#delete_if` methods.
12
- * Improved documentation.
22
+
23
+ - Improved unicode code point parsing and validation.
24
+ - Added `DotStrings::File#sort`, `DotStrings::File#sort!`, and `DotStrings::File#delete_if` methods.
25
+ - Improved documentation.
13
26
 
14
27
  ## [v0.2.0] - 2022-07-17
28
+
15
29
  ### Changed
16
- * Made some state transitions more strict.
17
- * Added option to ignore comments when serializing.
30
+
31
+ - Made some state transitions more strict.
32
+ - Added option to ignore comments when serializing.
18
33
 
19
34
  ## [v0.1.1] - 2022-07-12
35
+
20
36
  ### Changed
21
- * Escaping single quotes is now optional.
37
+
38
+ - Escaping single quotes is now optional.
22
39
 
23
40
  ## [v0.1.0] - 2022-07-06
41
+
24
42
  ### Added
25
- * Initial release.
26
43
 
44
+ - Initial release.
45
+
46
+ [v0.6.0]: https://github.com/raymondjavaxx/dotstrings/releases/tag/v0.6.0
47
+ [v0.5.0]: https://github.com/raymondjavaxx/dotstrings/releases/tag/v0.5.0
27
48
  [v0.4.0]: https://github.com/raymondjavaxx/dotstrings/releases/tag/v0.4.0
28
49
  [v0.3.0]: https://github.com/raymondjavaxx/dotstrings/releases/tag/v0.3.0
29
50
  [v0.2.0]: https://github.com/raymondjavaxx/dotstrings/releases/tag/v0.2.0
data/README.md CHANGED
@@ -36,15 +36,32 @@ file.items.each do |item|
36
36
  end
37
37
  ```
38
38
 
39
- ## Examples
39
+ ## Strict Mode
40
+
41
+ By default, the parser runs in *strict mode*. This means that it will raise a `DotStrings::ParsingError` if it encounters comments that are not tied to a key-value pair. For example, the following file will raise an error because the first comment is not followed by a key-value pair:
40
42
 
41
- ### Listing keys
43
+ ```
44
+ /* Spanish localizations */
45
+
46
+ /* Title for a button for accepting something */
47
+ "Accept" = "Aceptar";
48
+ ```
49
+
50
+ In *strict mode*, the parser will also raise an error if it encounters escaped characters that don't need to be escaped. For example, the following file will raise an error because the `?` character doesn't need to be escaped:
51
+
52
+ ```
53
+ /* Confirmation message */
54
+ "Are you sure\?" = "¿Estás seguro\?";
55
+ ```
56
+
57
+ If you want to disable *strict mode*, you can pass `strict: false` to the `DotStrings.parse_file()` method. This will match the behavior of Apple's own parser, which is more lenient.
42
58
 
43
59
  ```ruby
44
- puts file.keys
45
- # => ["key 1", "key 2", ...]
60
+ file = DotStrings.parse_file('es-ES/Localizable.strings', strict: false)
46
61
  ```
47
62
 
63
+ ## Examples
64
+
48
65
  ### Accessing items by key
49
66
 
50
67
  ```ruby
@@ -73,3 +90,5 @@ file << DotStrings::Item(
73
90
  ```ruby
74
91
  File.write('en-US/Localizable.strings', file.to_s)
75
92
  ```
93
+
94
+ For more examples, consult the [documentation](https://www.rubydoc.info/gems/dotstrings/DotStrings) or the [test suite](test).
@@ -45,12 +45,13 @@ module DotStrings
45
45
  # file = DotStrings::File.parse(io)
46
46
  #
47
47
  # @param io [IO] The IO object to parse.
48
+ # @param strict [Boolean] Whether to parse in strict mode.
48
49
  # @return [DotStrings::File] The parsed file.
49
50
  # @raise [DotStrings::ParsingError] if the file could not be parsed.
50
- def self.parse(io)
51
+ def self.parse(io, strict: true)
51
52
  items = []
52
53
 
53
- parser = Parser.new
54
+ parser = Parser.new(strict: strict)
54
55
  parser.on_item { |item| items << item }
55
56
  parser << normalize_encoding(io.read)
56
57
 
@@ -64,11 +65,12 @@ module DotStrings
64
65
  # file = DotStrings::File.parse_file('path/to/en.lproj/Localizable.strings')
65
66
  #
66
67
  # @param path [String] The path to the file to parse.
68
+ # @param strict [Boolean] Whether to parse in strict mode.
67
69
  # @return [DotStrings::File] The parsed file.
68
70
  # @raise [DotStrings::ParsingError] if the file could not be parsed.
69
- def self.parse_file(path)
71
+ def self.parse_file(path, strict: true)
70
72
  ::File.open(path, 'r') do |file|
71
- parse(file)
73
+ parse(file, strict: strict)
72
74
  end
73
75
  end
74
76
 
@@ -7,6 +7,9 @@ module DotStrings
7
7
 
8
8
  ##
9
9
  # Parser for .strings files.
10
+ #
11
+ # You can use this class directly, but it is recommended to use
12
+ # {File.parse} and {File.parse_file} wrappers instead.
10
13
  class Parser
11
14
  # Special tokens
12
15
  TOK_SLASH = '/'
@@ -39,7 +42,13 @@ module DotStrings
39
42
  STATE_UNICODE_SURROGATE = 11
40
43
  STATE_UNICODE_SURROGATE_U = 12
41
44
 
42
- def initialize
45
+ ##
46
+ # Returns a new Parser instance.
47
+ #
48
+ # @param strict [Boolean] Whether to parse in strict mode.
49
+ def initialize(strict: true)
50
+ @strict = strict
51
+
43
52
  @state = STATE_START
44
53
  @temp_state = nil
45
54
 
@@ -101,11 +110,7 @@ module DotStrings
101
110
  @buffer << ch
102
111
  end
103
112
  when STATE_COMMENT_END
104
- if ch == TOK_QUOTE
105
- @state = STATE_KEY
106
- else
107
- raise_error("Unexpected character '#{ch}'") unless whitespace?(ch)
108
- end
113
+ comment_end(ch)
109
114
  when STATE_KEY
110
115
  parse_string(ch) do |key|
111
116
  @current_key = key
@@ -174,7 +179,7 @@ module DotStrings
174
179
 
175
180
  def parse_string(ch, &block)
176
181
  if @escaping
177
- parse_escaped_character(ch, &block)
182
+ parse_escaped_character(ch)
178
183
  else
179
184
  case ch
180
185
  when TOK_BACKSLASH
@@ -188,6 +193,8 @@ module DotStrings
188
193
  end
189
194
  end
190
195
 
196
+ # rubocop:disable Metrics/CyclomaticComplexity
197
+
191
198
  def parse_escaped_character(ch)
192
199
  @escaping = false
193
200
 
@@ -206,13 +213,17 @@ module DotStrings
206
213
  when TOK_ZERO
207
214
  @buffer << "\0"
208
215
  else
209
- raise_error("Unexpected character '#{ch}'")
216
+ raise_error("Unexpected character '#{ch}'") if @strict
217
+ @buffer << ch
210
218
  end
211
219
  end
212
220
 
221
+ # rubocop:enable Metrics/CyclomaticComplexity
222
+
213
223
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
224
+
214
225
  def parse_unicode(ch, &block)
215
- raise_error("Unexpected character '#{ch}', expecting a hex digit") unless ch =~ TOK_HEX_DIGIT
226
+ raise_error("Unexpected character '#{ch}', expecting a hex digit") unless TOK_HEX_DIGIT.match?(ch)
216
227
 
217
228
  @unicode_buffer << ch
218
229
 
@@ -267,19 +278,33 @@ module DotStrings
267
278
  end
268
279
  end
269
280
 
270
- def start_value(ch)
281
+ def start_value(ch, resets: true)
271
282
  case ch
272
283
  when TOK_SLASH
273
284
  @state = STATE_COMMENT_START
274
- reset_state
285
+ reset_state if resets
275
286
  when TOK_QUOTE
276
287
  @state = STATE_KEY
277
- reset_state
288
+ reset_state if resets
278
289
  else
279
290
  raise_error("Unexpected character '#{ch}'") unless whitespace?(ch)
280
291
  end
281
292
  end
282
293
 
294
+ def comment_end(ch)
295
+ if @strict
296
+ # In strict mode, we expect a key to follow the comment.
297
+ if ch == TOK_QUOTE
298
+ @state = STATE_KEY
299
+ else
300
+ raise_error("Unexpected character '#{ch}'") unless whitespace?(ch)
301
+ end
302
+ else
303
+ # In lenient mode, we allow comments to be followed by anything.
304
+ start_value(ch, resets: false)
305
+ end
306
+ end
307
+
283
308
  def reset_state
284
309
  @current_comment = nil
285
310
  @current_key = nil
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DotStrings
4
- VERSION = '0.4.0'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/dotstrings.rb CHANGED
@@ -12,9 +12,10 @@ module DotStrings
12
12
  # This is a convenience method for {DotStrings::File.parse}.
13
13
  #
14
14
  # @param io [IO] The IO object to parse.
15
+ # @param strict [Boolean] Whether to parse in strict mode.
15
16
  # @return [DotStrings::File] The parsed file.
16
- def self.parse(io)
17
- File.parse(io)
17
+ def self.parse(io, strict: true)
18
+ File.parse(io, strict: strict)
18
19
  end
19
20
 
20
21
  ##
@@ -23,8 +24,9 @@ module DotStrings
23
24
  # This is a convenience method for {DotStrings::File.parse_file}.
24
25
  #
25
26
  # @param path [String] The path to the .strings file to parse.
27
+ # @param strict [Boolean] Whether to parse in strict mode.
26
28
  # @return [DotStrings::File] The parsed file.
27
- def self.parse_file(path)
28
- File.parse_file(path)
29
+ def self.parse_file(path, strict: true)
30
+ File.parse_file(path, strict: strict)
29
31
  end
30
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotstrings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ramon Torres
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-18 00:00:00.000000000 Z
11
+ date: 2024-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -56,30 +56,30 @@ dependencies:
56
56
  name: rubocop
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 1.50.2
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
- version: '0'
68
+ version: 1.50.2
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-minitest
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 0.30.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
- version: '0'
82
+ version: 0.30.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-rake
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -138,15 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
138
  requirements:
139
139
  - - ">="
140
140
  - !ruby/object:Gem::Version
141
- version: 2.5.0
141
+ version: 2.6.0
142
142
  required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - ">="
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  requirements: []
148
- rubyforge_project:
149
- rubygems_version: 2.7.6
148
+ rubygems_version: 3.4.10
150
149
  signing_key:
151
150
  specification_version: 4
152
151
  summary: Parse and create .strings files used in localization of iOS and macOS apps.