dsv7-parser 7.0.0 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +7 -1
- data/README.md +126 -51
- data/Rakefile +38 -0
- data/dsv7-parser.gemspec +5 -1
- data/lib/dsv7/lex.rb +15 -2
- data/lib/dsv7/parser/engine.rb +10 -0
- data/lib/dsv7/parser/io_util.rb +26 -0
- data/lib/dsv7/parser/version.rb +4 -1
- data/lib/dsv7/parser.rb +110 -8
- data/lib/dsv7/stream.rb +26 -0
- data/lib/dsv7/validator/cardinality.rb +6 -0
- data/lib/dsv7/validator/core.rb +18 -0
- data/lib/dsv7/validator/line_analyzer.rb +21 -5
- data/lib/dsv7/validator/line_analyzer_common.rb +25 -0
- data/lib/dsv7/validator/result.rb +34 -0
- data/lib/dsv7/validator/schemas/base.rb +26 -0
- data/lib/dsv7/validator/schemas/erg_schema.rb +5 -1
- data/lib/dsv7/validator/schemas/vml_schema.rb +3 -1
- data/lib/dsv7/validator/schemas/vrl_schema.rb +5 -1
- data/lib/dsv7/validator/schemas/wk_schema.rb +8 -1
- data/lib/dsv7/validator/types/common.rb +13 -0
- data/lib/dsv7/validator/types/datetime.rb +12 -0
- data/lib/dsv7/validator/types/enums1.rb +10 -0
- data/lib/dsv7/validator/types/enums2.rb +10 -0
- data/lib/dsv7/validator/types.rb +8 -0
- data/lib/dsv7/validator.rb +49 -2
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c363432be089a4a08ccd0f9c1356b47c8a537436aebd5e75000d767dd8c531b6
|
|
4
|
+
data.tar.gz: 7683d1b49fe75fa94f0682db2dcc6720b31b250d5657f1171799630807c57248
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66254952933799a4d2f823b69731fda0c43a9509f7edfc96a26aac47a4a97b8677ecf4362e957c5b68aec2c4d6156f6276c824354f625449d48aede884ec7241
|
|
7
|
+
data.tar.gz: 9af9cae918a817ff1c1f927e577b84b01cddb903fc77ba364d97e86271d3a3835dd43bead77d808b8a79075d789c3c28967298e64411cd2b9e9b661f83945a6e
|
data/.yardopts
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
dsv7-parser (7.0.
|
|
4
|
+
dsv7-parser (7.0.1)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
@@ -9,6 +9,8 @@ GEM
|
|
|
9
9
|
ast (2.4.3)
|
|
10
10
|
docile (1.4.1)
|
|
11
11
|
json (2.15.0)
|
|
12
|
+
kramdown (2.5.1)
|
|
13
|
+
rexml (>= 3.3.9)
|
|
12
14
|
language_server-protocol (3.17.0.5)
|
|
13
15
|
lint_roller (1.1.0)
|
|
14
16
|
minitest (5.25.5)
|
|
@@ -21,6 +23,7 @@ GEM
|
|
|
21
23
|
rainbow (3.1.1)
|
|
22
24
|
rake (13.3.0)
|
|
23
25
|
regexp_parser (2.11.3)
|
|
26
|
+
rexml (3.4.4)
|
|
24
27
|
rubocop (1.81.0)
|
|
25
28
|
json (~> 2.3)
|
|
26
29
|
language_server-protocol (~> 3.17.0.2)
|
|
@@ -45,6 +48,7 @@ GEM
|
|
|
45
48
|
unicode-display_width (3.2.0)
|
|
46
49
|
unicode-emoji (~> 4.1)
|
|
47
50
|
unicode-emoji (4.1.0)
|
|
51
|
+
yard (0.9.37)
|
|
48
52
|
|
|
49
53
|
PLATFORMS
|
|
50
54
|
ruby
|
|
@@ -52,10 +56,12 @@ PLATFORMS
|
|
|
52
56
|
|
|
53
57
|
DEPENDENCIES
|
|
54
58
|
dsv7-parser!
|
|
59
|
+
kramdown
|
|
55
60
|
minitest (>= 5.18)
|
|
56
61
|
rake (>= 13.0)
|
|
57
62
|
rubocop
|
|
58
63
|
simplecov
|
|
64
|
+
yard
|
|
59
65
|
|
|
60
66
|
BUNDLED WITH
|
|
61
67
|
2.7.2
|
data/README.md
CHANGED
|
@@ -14,18 +14,18 @@ Requirements
|
|
|
14
14
|
|
|
15
15
|
Basic envelope checks plus element validation for all four list types (WKDL, VML, ERG, VRL) are available via one entrypoint:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
~~~
|
|
18
18
|
require 'dsv7/parser'
|
|
19
19
|
|
|
20
20
|
# Pass a path, IO, or a String with file content
|
|
21
21
|
result = Dsv7::Validator.validate('path/to/file.DSV7')
|
|
22
22
|
|
|
23
|
-
puts
|
|
24
|
-
puts
|
|
25
|
-
puts
|
|
26
|
-
puts
|
|
27
|
-
puts
|
|
28
|
-
|
|
23
|
+
puts 'valid? ' + result.valid?.to_s
|
|
24
|
+
puts 'list_type: ' + result.list_type.to_s
|
|
25
|
+
puts 'version: ' + result.version.to_s
|
|
26
|
+
puts 'errors: ' + result.errors.inspect
|
|
27
|
+
puts 'warnings: ' + result.warnings.inspect
|
|
28
|
+
~~~
|
|
29
29
|
|
|
30
30
|
Accepted inputs:
|
|
31
31
|
|
|
@@ -49,7 +49,7 @@ Filename guidance (when validating by path):
|
|
|
49
49
|
|
|
50
50
|
Minimal example (generic list type):
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
~~~
|
|
53
53
|
content = <<~DSV
|
|
54
54
|
FORMAT:Vereinsmeldeliste;7;
|
|
55
55
|
DATA;ok
|
|
@@ -58,11 +58,11 @@ DSV
|
|
|
58
58
|
|
|
59
59
|
result = Dsv7::Validator.validate(content)
|
|
60
60
|
puts result.valid? # => true
|
|
61
|
-
|
|
61
|
+
~~~
|
|
62
62
|
|
|
63
63
|
Wettkampfdefinitionsliste validation (cardinality + attribute types):
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
~~~
|
|
66
66
|
wkdl = <<~DSV
|
|
67
67
|
FORMAT:Wettkampfdefinitionsliste;7;
|
|
68
68
|
ERZEUGER:Soft;1.0;mail@example.com;
|
|
@@ -83,11 +83,11 @@ wk_result = Dsv7::Validator.validate(wkdl)
|
|
|
83
83
|
puts wk_result.valid? # => true
|
|
84
84
|
puts wk_result.errors # => []
|
|
85
85
|
puts wk_result.warnings # => []
|
|
86
|
-
|
|
86
|
+
~~~
|
|
87
87
|
|
|
88
88
|
Vereinsmeldeliste validation (cardinality + attribute types):
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
~~~
|
|
91
91
|
vml = <<~DSV
|
|
92
92
|
FORMAT:Vereinsmeldeliste;7;
|
|
93
93
|
ERZEUGER:Soft;1.0;mail@example.com;
|
|
@@ -101,27 +101,91 @@ DSV
|
|
|
101
101
|
|
|
102
102
|
vml_result = Dsv7::Validator.validate(vml)
|
|
103
103
|
puts vml_result.valid? # => true
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Validated
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
104
|
+
~~~
|
|
105
|
+
|
|
106
|
+
## Validated elements
|
|
107
|
+
|
|
108
|
+
WKDL (Wettkampfdefinitionsliste)
|
|
109
|
+
|
|
110
|
+
- `ERZEUGER`
|
|
111
|
+
- `VERANSTALTUNG`
|
|
112
|
+
- `VERANSTALTUNGSORT`
|
|
113
|
+
- `AUSSCHREIBUNGIMNETZ`
|
|
114
|
+
- `VERANSTALTER`
|
|
115
|
+
- `AUSRICHTER`
|
|
116
|
+
- `MELDEADRESSE`
|
|
117
|
+
- `MELDESCHLUSS`
|
|
118
|
+
- `BANKVERBINDUNG`
|
|
119
|
+
- `BESONDERES`
|
|
120
|
+
- `NACHWEIS`
|
|
121
|
+
- `ABSCHNITT`
|
|
122
|
+
- `WETTKAMPF`
|
|
123
|
+
- `WERTUNG`
|
|
124
|
+
- `MELDEGELD`
|
|
125
|
+
|
|
126
|
+
VML (Vereinsmeldeliste)
|
|
127
|
+
|
|
128
|
+
- `ERZEUGER`
|
|
129
|
+
- `VERANSTALTUNG`
|
|
130
|
+
- `ABSCHNITT`
|
|
131
|
+
- `WETTKAMPF`
|
|
132
|
+
- `VEREIN`
|
|
133
|
+
- `ANSPRECHPARTNER`
|
|
134
|
+
- `KARIMELDUNG`
|
|
135
|
+
- `KARIABSCHNITT`
|
|
136
|
+
- `TRAINER`
|
|
137
|
+
- `PNMELDUNG`
|
|
138
|
+
- `HANDICAP`
|
|
139
|
+
- `STARTPN`
|
|
140
|
+
- `STMELDUNG`
|
|
141
|
+
- `STARTST`
|
|
142
|
+
- `STAFFELPERSON`
|
|
143
|
+
|
|
144
|
+
ERG (Wettkampfergebnisliste)
|
|
145
|
+
|
|
146
|
+
- `ERZEUGER`
|
|
147
|
+
- `VERANSTALTUNG`
|
|
148
|
+
- `VERANSTALTER`
|
|
149
|
+
- `AUSRICHTER`
|
|
150
|
+
- `ABSCHNITT`
|
|
151
|
+
- `KAMPFGERICHT`
|
|
152
|
+
- `WETTKAMPF`
|
|
153
|
+
- `WERTUNG`
|
|
154
|
+
- `VEREIN`
|
|
155
|
+
- `PNERGEBNIS`
|
|
156
|
+
- `PNZWISCHENZEIT`
|
|
157
|
+
- `PNREAKTION`
|
|
158
|
+
- `STAFFELERGEBNIS`
|
|
159
|
+
- `STERGEBNIS`
|
|
160
|
+
- `STAFFELPERSON`
|
|
161
|
+
- `STZWISCHENZEIT`
|
|
162
|
+
- `STABLOESE`
|
|
163
|
+
|
|
164
|
+
VRL (Vereinsergebnisliste)
|
|
165
|
+
|
|
166
|
+
- `ERZEUGER`
|
|
167
|
+
- `VERANSTALTUNG`
|
|
168
|
+
- `VERANSTALTER`
|
|
169
|
+
- `AUSRICHTER`
|
|
170
|
+
- `ABSCHNITT`
|
|
171
|
+
- `KAMPFGERICHT`
|
|
172
|
+
- `WETTKAMPF`
|
|
173
|
+
- `WERTUNG`
|
|
174
|
+
- `VEREIN`
|
|
175
|
+
- `PERSON`
|
|
176
|
+
- `PERSONENERGEBNIS`
|
|
177
|
+
- `PNZWISCHENZEIT`
|
|
178
|
+
- `PNREAKTION`
|
|
179
|
+
- `STAFFEL`
|
|
180
|
+
- `STAFFELPERSON`
|
|
181
|
+
- `STAFFELERGEBNIS`
|
|
182
|
+
- `STERGEBNIS`
|
|
183
|
+
- `STZWISCHENZEIT`
|
|
184
|
+
- `STABLOESE`
|
|
121
185
|
|
|
122
186
|
Common error and warning examples:
|
|
123
187
|
|
|
124
|
-
|
|
188
|
+
~~~
|
|
125
189
|
# 1) Unknown list type and missing DATEIENDE
|
|
126
190
|
bad = "FORMAT:Unbekannt;7;\n"
|
|
127
191
|
r = Dsv7::Validator.validate(bad)
|
|
@@ -154,7 +218,7 @@ begin
|
|
|
154
218
|
ensure
|
|
155
219
|
File.delete('tmp/badname.txt')
|
|
156
220
|
end
|
|
157
|
-
|
|
221
|
+
~~~
|
|
158
222
|
|
|
159
223
|
## Parser (Streaming: WKDL, VML, ERG, VRL)
|
|
160
224
|
|
|
@@ -173,7 +237,7 @@ It is tolerant and focuses on extracting elements efficiently; use the validator
|
|
|
173
237
|
|
|
174
238
|
Generic example (auto-detect list type):
|
|
175
239
|
|
|
176
|
-
|
|
240
|
+
~~~
|
|
177
241
|
enum = Dsv7::Parser.parse('path/to/file.DSV7')
|
|
178
242
|
enum.each do |type, payload, line_number|
|
|
179
243
|
case type
|
|
@@ -185,7 +249,7 @@ enum.each do |type, payload, line_number|
|
|
|
185
249
|
# reached DATEIENDE
|
|
186
250
|
end
|
|
187
251
|
end
|
|
188
|
-
|
|
252
|
+
~~~
|
|
189
253
|
|
|
190
254
|
Key points:
|
|
191
255
|
|
|
@@ -196,7 +260,7 @@ Key points:
|
|
|
196
260
|
|
|
197
261
|
Basic example (block style):
|
|
198
262
|
|
|
199
|
-
|
|
263
|
+
~~~
|
|
200
264
|
require 'dsv7/parser'
|
|
201
265
|
|
|
202
266
|
content = <<~DSV
|
|
@@ -220,20 +284,20 @@ Dsv7::Parser.parse(content) do |type, payload, line_number|
|
|
|
220
284
|
p [:end, line_number]
|
|
221
285
|
end
|
|
222
286
|
end
|
|
223
|
-
|
|
287
|
+
~~~
|
|
224
288
|
|
|
225
289
|
Enumerator style:
|
|
226
290
|
|
|
227
|
-
|
|
291
|
+
~~~
|
|
228
292
|
enum = Dsv7::Parser.parse('path/to/2002-03-10-Duisburg-Wk.DSV7')
|
|
229
293
|
enum.each do |type, payload, line_number|
|
|
230
294
|
# same triplets as the block example
|
|
231
295
|
end
|
|
232
|
-
|
|
296
|
+
~~~
|
|
233
297
|
|
|
234
298
|
Building a simple structure (header + elements) from the stream:
|
|
235
299
|
|
|
236
|
-
|
|
300
|
+
~~~
|
|
237
301
|
data = { format: nil, elements: [] }
|
|
238
302
|
|
|
239
303
|
Dsv7::Parser.parse(content) do |type, payload, line_number|
|
|
@@ -249,24 +313,24 @@ end
|
|
|
249
313
|
wettkaempfe = data[:elements]
|
|
250
314
|
.select { |e| e[:name] == 'WETTKAMPF' }
|
|
251
315
|
.map { |e| e[:attrs] } # arrays of attributes per row
|
|
252
|
-
|
|
316
|
+
~~~
|
|
253
317
|
|
|
254
318
|
Combining validation with parsing:
|
|
255
319
|
|
|
256
|
-
|
|
320
|
+
~~~
|
|
257
321
|
result = Dsv7::Validator.validate('path/to/file.DSV7')
|
|
258
322
|
if result.valid?
|
|
259
323
|
Dsv7::Parser.parse('path/to/file.DSV7') do |type, payload, line_number|
|
|
260
324
|
# consume events
|
|
261
325
|
end
|
|
262
326
|
else
|
|
263
|
-
warn
|
|
327
|
+
warn 'Invalid DSV7: ' + result.errors.join('; ')
|
|
264
328
|
end
|
|
265
|
-
|
|
329
|
+
~~~
|
|
266
330
|
|
|
267
331
|
VML usage mirrors WKDL:
|
|
268
332
|
|
|
269
|
-
|
|
333
|
+
~~~
|
|
270
334
|
content = <<~DSV
|
|
271
335
|
FORMAT:Vereinsmeldeliste;7;
|
|
272
336
|
ERZEUGER:Soft;1.0;mail@example.com;
|
|
@@ -281,11 +345,11 @@ DSV
|
|
|
281
345
|
Dsv7::Parser.parse(content) do |type, payload, line_number|
|
|
282
346
|
# same :format, :element, :end semantics
|
|
283
347
|
end
|
|
284
|
-
|
|
348
|
+
~~~
|
|
285
349
|
|
|
286
350
|
ERG usage mirrors WKDL as well:
|
|
287
351
|
|
|
288
|
-
|
|
352
|
+
~~~
|
|
289
353
|
content = <<~DSV
|
|
290
354
|
FORMAT:Wettkampfergebnisliste;7;
|
|
291
355
|
ERZEUGER:Soft;1.0;mail@example.com;
|
|
@@ -299,11 +363,11 @@ DSV
|
|
|
299
363
|
Dsv7::Parser.parse(content) do |type, payload, line_number|
|
|
300
364
|
# same :format, :element, :end semantics
|
|
301
365
|
end
|
|
302
|
-
|
|
366
|
+
~~~
|
|
303
367
|
|
|
304
368
|
VRL usage mirrors WKDL as well:
|
|
305
369
|
|
|
306
|
-
|
|
370
|
+
~~~
|
|
307
371
|
content = <<~DSV
|
|
308
372
|
FORMAT:Vereinsergebnisliste;7;
|
|
309
373
|
ERZEUGER:Soft;1.0;mail@example.com;
|
|
@@ -317,7 +381,7 @@ DSV
|
|
|
317
381
|
Dsv7::Parser.parse(content) do |type, payload, line_number|
|
|
318
382
|
# same :format, :element, :end semantics
|
|
319
383
|
end
|
|
320
|
-
|
|
384
|
+
~~~
|
|
321
385
|
|
|
322
386
|
Errors and edge cases:
|
|
323
387
|
|
|
@@ -332,11 +396,22 @@ Errors and edge cases:
|
|
|
332
396
|
- Tests use Minitest and live under `test/dsv7/`.
|
|
333
397
|
- Version is defined in `lib/dsv7/parser/version.rb`.
|
|
334
398
|
|
|
399
|
+
## API Documentation (YARD)
|
|
400
|
+
|
|
401
|
+
- Hosted docs (Rubydoc): https://www.rubydoc.info/gems/dsv7-parser
|
|
402
|
+
- Generate locally: `bundle install && bundle exec rake yard`
|
|
403
|
+
- Output is written to `doc/`.
|
|
404
|
+
|
|
405
|
+
Notes:
|
|
406
|
+
|
|
407
|
+
- Public API is focused on `Dsv7::Validator.validate` and the `Dsv7::Parser.parse*` helpers.
|
|
408
|
+
- Internal helpers are annotated with `@api private` and hidden from the default docs.
|
|
409
|
+
|
|
335
410
|
## Compact ERG Example
|
|
336
411
|
|
|
337
412
|
Minimal Wettkampfergebnisliste validation and parsing in one go:
|
|
338
413
|
|
|
339
|
-
|
|
414
|
+
~~~
|
|
340
415
|
require 'dsv7/parser'
|
|
341
416
|
|
|
342
417
|
content = <<~DSV
|
|
@@ -365,6 +440,6 @@ if result.valid?
|
|
|
365
440
|
end
|
|
366
441
|
end
|
|
367
442
|
else
|
|
368
|
-
warn
|
|
443
|
+
warn 'Invalid ERG: ' + result.errors.join('; ')
|
|
369
444
|
end
|
|
370
|
-
|
|
445
|
+
~~~
|
data/Rakefile
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
require 'bundler/gem_tasks'
|
|
4
4
|
require 'rake/testtask'
|
|
5
5
|
require 'rubocop/rake_task'
|
|
6
|
+
begin
|
|
7
|
+
require 'yard'
|
|
8
|
+
require 'yard/rake/yardoc_task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
# YARD is a dev dependency; tasks are available when installed
|
|
11
|
+
end
|
|
6
12
|
|
|
7
13
|
Rake::TestTask.new(:test) do |t|
|
|
8
14
|
t.libs << 'lib'
|
|
@@ -22,3 +28,35 @@ task lint: :rubocop
|
|
|
22
28
|
|
|
23
29
|
desc 'CI: run tests and lint'
|
|
24
30
|
task ci: %i[test lint]
|
|
31
|
+
|
|
32
|
+
if defined?(YARD)
|
|
33
|
+
desc 'Generate YARD documentation into doc/'
|
|
34
|
+
YARD::Rake::YardocTask.new(:yard) do |t|
|
|
35
|
+
# Parse only Ruby sources; README is provided via --readme for markup rendering
|
|
36
|
+
t.files = FileList['lib/**/*.rb']
|
|
37
|
+
t.options = [
|
|
38
|
+
'--no-cache',
|
|
39
|
+
'--markup', 'markdown',
|
|
40
|
+
'--markup-provider', 'kramdown',
|
|
41
|
+
'--readme', 'README.md',
|
|
42
|
+
'--hide-api', 'private'
|
|
43
|
+
]
|
|
44
|
+
end
|
|
45
|
+
# Back-compat target for `rake doc`
|
|
46
|
+
task doc: :yard
|
|
47
|
+
# Generate full internal docs (includes @api private and private methods)
|
|
48
|
+
desc 'Generate full YARD docs (including private API) into doc-internal/'
|
|
49
|
+
YARD::Rake::YardocTask.new(:yard_full) do |t|
|
|
50
|
+
t.files = FileList['lib/**/*.rb']
|
|
51
|
+
t.options = [
|
|
52
|
+
'--no-cache',
|
|
53
|
+
'--markup', 'markdown',
|
|
54
|
+
'--markup-provider', 'kramdown',
|
|
55
|
+
'--readme', 'README.md',
|
|
56
|
+
'--private',
|
|
57
|
+
'-o', 'doc-internal'
|
|
58
|
+
]
|
|
59
|
+
end
|
|
60
|
+
task 'docs:full' => :yard_full
|
|
61
|
+
task docs: :yard
|
|
62
|
+
end
|
data/dsv7-parser.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.email = ['maintheme@gmail.com']
|
|
10
10
|
|
|
11
11
|
spec.summary = 'SAX parser for the DSV7 swim file format'
|
|
12
|
-
spec.description = 'Ruby gem for a DSV7
|
|
12
|
+
spec.description = 'Ruby gem for a SAX parser targeting the DSV7 swim file format'
|
|
13
13
|
spec.homepage = 'https://github.com/bigcurl/dsv7-parser'
|
|
14
14
|
spec.license = 'MIT'
|
|
15
15
|
|
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
19
|
spec.metadata['source_code_uri'] = spec.homepage
|
|
20
20
|
spec.metadata['changelog_uri'] = spec.homepage
|
|
21
|
+
spec.metadata['documentation_uri'] = 'https://www.rubydoc.info/gems/dsv7-parser'
|
|
21
22
|
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
22
23
|
|
|
23
24
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
@@ -26,6 +27,9 @@ Gem::Specification.new do |spec|
|
|
|
26
27
|
|
|
27
28
|
spec.require_paths = ['lib']
|
|
28
29
|
|
|
30
|
+
# Include top-level docs in packaged RDoc
|
|
31
|
+
spec.extra_rdoc_files = ['README.md', 'LICENSE']
|
|
32
|
+
|
|
29
33
|
# Runtime dependencies (none yet)
|
|
30
34
|
# spec.add_dependency "nokogiri", ">= 1.14"
|
|
31
35
|
|
data/lib/dsv7/lex.rb
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dsv7
|
|
4
|
+
##
|
|
5
|
+
# Lexical helpers for simple DSV7 tokens.
|
|
6
|
+
#
|
|
7
|
+
# - {parse_format} extracts the list type and version from an exact
|
|
8
|
+
# `FORMAT:<Listentyp>;<Version>;` line.
|
|
9
|
+
# - {element} splits an element line into its name and attributes.
|
|
10
|
+
#
|
|
11
|
+
# These functions are intentionally minimal and do not perform semantic checks.
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
4
14
|
module Lex
|
|
5
15
|
module_function
|
|
6
16
|
|
|
7
|
-
# Parses a FORMAT line.
|
|
17
|
+
# Parses a FORMAT line.
|
|
18
|
+
# @param line [String]
|
|
19
|
+
# @return [Array<String>, nil] Pair of [list_type, version] or nil if not a FORMAT line
|
|
8
20
|
def parse_format(line)
|
|
9
21
|
m = line.match(/^FORMAT:([^;]+);([^;]+);$/)
|
|
10
22
|
return nil unless m
|
|
@@ -13,7 +25,8 @@ module Dsv7
|
|
|
13
25
|
end
|
|
14
26
|
|
|
15
27
|
# Splits an element content line into name and attributes.
|
|
16
|
-
#
|
|
28
|
+
# @param content [String]
|
|
29
|
+
# @return [Array, nil] Tuple `[name, attrs]` or nil if the line is not an element line
|
|
17
30
|
def element(content)
|
|
18
31
|
return nil unless content.include?(':')
|
|
19
32
|
|
data/lib/dsv7/parser/engine.rb
CHANGED
|
@@ -8,11 +8,21 @@ require_relative 'io_util'
|
|
|
8
8
|
module Dsv7
|
|
9
9
|
module Parser
|
|
10
10
|
# Internal engine that implements the streaming mechanics.
|
|
11
|
+
##
|
|
12
|
+
# Internal streaming engine used by {Dsv7::Parser}.
|
|
13
|
+
#
|
|
14
|
+
# Converts an input (path/IO/String) into a stream of parser events. It
|
|
15
|
+
# performs the same line normalization as the validator (via Stream/IoUtil),
|
|
16
|
+
# strips inline comments, and stops emitting at `DATEIENDE`.
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
11
19
|
class Engine
|
|
20
|
+
# @api private
|
|
12
21
|
def self.stream_any(input, emitter)
|
|
13
22
|
new(input, emitter).stream_any
|
|
14
23
|
end
|
|
15
24
|
|
|
25
|
+
# @api private
|
|
16
26
|
def self.stream_list(input, emitter, expected_list_type)
|
|
17
27
|
new(input, emitter).stream_list(expected_list_type)
|
|
18
28
|
end
|
data/lib/dsv7/parser/io_util.rb
CHANGED
|
@@ -6,8 +6,21 @@ require_relative '../stream'
|
|
|
6
6
|
module Dsv7
|
|
7
7
|
module Parser
|
|
8
8
|
module IoUtil
|
|
9
|
+
##
|
|
10
|
+
# Parser IO utilities.
|
|
11
|
+
#
|
|
12
|
+
# `to_io` converts supported inputs to an IO; `with_io` manages lifetime
|
|
13
|
+
# and applies Stream normalization; `each_content_line` yields non‑empty,
|
|
14
|
+
# comment‑stripped content lines with 1‑based line numbers.
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
|
|
9
18
|
module_function
|
|
10
19
|
|
|
20
|
+
# Convert supported inputs into an IO instance.
|
|
21
|
+
# @param input [IO, String]
|
|
22
|
+
# @return [IO]
|
|
23
|
+
# @raise [ArgumentError] for unsupported input types
|
|
11
24
|
def to_io(input)
|
|
12
25
|
return input if input.respond_to?(:read)
|
|
13
26
|
return File.open(input, 'rb') if input.is_a?(String) && File.file?(input)
|
|
@@ -16,6 +29,12 @@ module Dsv7
|
|
|
16
29
|
raise ArgumentError, 'Unsupported input; pass IO, file path String, or content String'
|
|
17
30
|
end
|
|
18
31
|
|
|
32
|
+
# Open/normalize an input and yield an IO. Closes the IO when it was
|
|
33
|
+
# opened from a file path.
|
|
34
|
+
# @param input [IO, String]
|
|
35
|
+
# @yield [io]
|
|
36
|
+
# @yieldparam io [IO]
|
|
37
|
+
# @return [void]
|
|
19
38
|
def with_io(input)
|
|
20
39
|
close_after = input.is_a?(String) && File.file?(input)
|
|
21
40
|
io = to_io(input)
|
|
@@ -26,6 +45,13 @@ module Dsv7
|
|
|
26
45
|
io&.close if close_after
|
|
27
46
|
end
|
|
28
47
|
|
|
48
|
+
# Yield each non-empty, comment-stripped content line with 1-based
|
|
49
|
+
# line numbers.
|
|
50
|
+
# @param io [IO]
|
|
51
|
+
# @yield [content, line_number]
|
|
52
|
+
# @yieldparam content [String]
|
|
53
|
+
# @yieldparam line_number [Integer]
|
|
54
|
+
# @return [void]
|
|
29
55
|
def each_content_line(io)
|
|
30
56
|
ln = 0
|
|
31
57
|
io.each_line("\n") do |raw|
|