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 +4 -4
- data/CHANGELOG.md +30 -9
- data/README.md +23 -4
- data/lib/dotstrings/file.rb +6 -4
- data/lib/dotstrings/parser.rb +37 -12
- data/lib/dotstrings/version.rb +1 -1
- data/lib/dotstrings.rb +6 -4
- metadata +12 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3043892fd5f3068811c63cd3da980cfef6779522359be1974dea0b3be6d4f60c
|
4
|
+
data.tar.gz: eb04dbb9ff868273b783a1f8337d4cd11098cc0450a4676beb241a0b88e49dff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
6
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
17
|
-
|
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
|
-
|
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
|
-
##
|
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
|
-
|
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
|
-
|
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).
|
data/lib/dotstrings/file.rb
CHANGED
@@ -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
|
|
data/lib/dotstrings/parser.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
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
|
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
|
data/lib/dotstrings/version.rb
CHANGED
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
|
+
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:
|
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:
|
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:
|
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:
|
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:
|
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.
|
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
|
-
|
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.
|