dsv7-parser 7.0.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb8097275fb6859296653a95615ebd304fcb53a36436118946b60e035b3ccdaf
4
- data.tar.gz: cc2693be6d15b7cc2654bf378f3288cd87782ec40bc4b04c5f66c52dcdaf26c3
3
+ metadata.gz: c363432be089a4a08ccd0f9c1356b47c8a537436aebd5e75000d767dd8c531b6
4
+ data.tar.gz: 7683d1b49fe75fa94f0682db2dcc6720b31b250d5657f1171799630807c57248
5
5
  SHA512:
6
- metadata.gz: f705afebef80f7863205632454a92f5bd2b5c910c8df0ec94ae684bcb3c9b6bc36f4afe8c887a57e537eea3b223525c8fff66e43acb007c773b179cccacb9025
7
- data.tar.gz: 13628c729df524abc3a5eb2cbb9378fd76845a6cf8f258e9ef24612dcf64d9c1b22f98b96c0bf18757851513367949b91ba3b439476f0c88a328c16ea1879faf
6
+ metadata.gz: 66254952933799a4d2f823b69731fda0c43a9509f7edfc96a26aac47a4a97b8677ecf4362e957c5b68aec2c4d6156f6276c824354f625449d48aede884ec7241
7
+ data.tar.gz: 9af9cae918a817ff1c1f927e577b84b01cddb903fc77ba364d97e86271d3a3835dd43bead77d808b8a79075d789c3c28967298e64411cd2b9e9b661f83945a6e
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --markup markdown
2
+ --markup-provider kramdown
3
+ --readme README.md
4
+ --hide-api private
5
+ lib/**/*.rb
data/Gemfile CHANGED
@@ -12,4 +12,8 @@ end
12
12
 
13
13
  group :development do
14
14
  gem 'rubocop', require: false
15
+ # YARD is used for generating API documentation
16
+ gem 'yard', require: false
17
+ # Kramdown provides robust Markdown rendering for YARD
18
+ gem 'kramdown', require: false
15
19
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dsv7-parser (7.0.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 "valid? #{result.valid?}"
24
- puts "list_type: #{result.list_type}"
25
- puts "version: #{result.version}"
26
- puts "errors: #{result.errors.inspect}"
27
- puts "warnings: #{result.warnings.inspect}"
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,7 +101,7 @@ DSV
101
101
 
102
102
  vml_result = Dsv7::Validator.validate(vml)
103
103
  puts vml_result.valid? # => true
104
- ```
104
+ ~~~
105
105
 
106
106
  ## Validated elements
107
107
 
@@ -185,7 +185,7 @@ VRL (Vereinsergebnisliste)
185
185
 
186
186
  Common error and warning examples:
187
187
 
188
- ```
188
+ ~~~
189
189
  # 1) Unknown list type and missing DATEIENDE
190
190
  bad = "FORMAT:Unbekannt;7;\n"
191
191
  r = Dsv7::Validator.validate(bad)
@@ -218,7 +218,7 @@ begin
218
218
  ensure
219
219
  File.delete('tmp/badname.txt')
220
220
  end
221
- ```
221
+ ~~~
222
222
 
223
223
  ## Parser (Streaming: WKDL, VML, ERG, VRL)
224
224
 
@@ -237,7 +237,7 @@ It is tolerant and focuses on extracting elements efficiently; use the validator
237
237
 
238
238
  Generic example (auto-detect list type):
239
239
 
240
- ```
240
+ ~~~
241
241
  enum = Dsv7::Parser.parse('path/to/file.DSV7')
242
242
  enum.each do |type, payload, line_number|
243
243
  case type
@@ -249,7 +249,7 @@ enum.each do |type, payload, line_number|
249
249
  # reached DATEIENDE
250
250
  end
251
251
  end
252
- ```
252
+ ~~~
253
253
 
254
254
  Key points:
255
255
 
@@ -260,7 +260,7 @@ Key points:
260
260
 
261
261
  Basic example (block style):
262
262
 
263
- ```
263
+ ~~~
264
264
  require 'dsv7/parser'
265
265
 
266
266
  content = <<~DSV
@@ -284,20 +284,20 @@ Dsv7::Parser.parse(content) do |type, payload, line_number|
284
284
  p [:end, line_number]
285
285
  end
286
286
  end
287
- ```
287
+ ~~~
288
288
 
289
289
  Enumerator style:
290
290
 
291
- ```
291
+ ~~~
292
292
  enum = Dsv7::Parser.parse('path/to/2002-03-10-Duisburg-Wk.DSV7')
293
293
  enum.each do |type, payload, line_number|
294
294
  # same triplets as the block example
295
295
  end
296
- ```
296
+ ~~~
297
297
 
298
298
  Building a simple structure (header + elements) from the stream:
299
299
 
300
- ```
300
+ ~~~
301
301
  data = { format: nil, elements: [] }
302
302
 
303
303
  Dsv7::Parser.parse(content) do |type, payload, line_number|
@@ -313,24 +313,24 @@ end
313
313
  wettkaempfe = data[:elements]
314
314
  .select { |e| e[:name] == 'WETTKAMPF' }
315
315
  .map { |e| e[:attrs] } # arrays of attributes per row
316
- ```
316
+ ~~~
317
317
 
318
318
  Combining validation with parsing:
319
319
 
320
- ```
320
+ ~~~
321
321
  result = Dsv7::Validator.validate('path/to/file.DSV7')
322
322
  if result.valid?
323
323
  Dsv7::Parser.parse('path/to/file.DSV7') do |type, payload, line_number|
324
324
  # consume events
325
325
  end
326
326
  else
327
- warn "Invalid DSV7: #{result.errors.join('; ')}"
327
+ warn 'Invalid DSV7: ' + result.errors.join('; ')
328
328
  end
329
- ```
329
+ ~~~
330
330
 
331
331
  VML usage mirrors WKDL:
332
332
 
333
- ```
333
+ ~~~
334
334
  content = <<~DSV
335
335
  FORMAT:Vereinsmeldeliste;7;
336
336
  ERZEUGER:Soft;1.0;mail@example.com;
@@ -345,11 +345,11 @@ DSV
345
345
  Dsv7::Parser.parse(content) do |type, payload, line_number|
346
346
  # same :format, :element, :end semantics
347
347
  end
348
- ```
348
+ ~~~
349
349
 
350
350
  ERG usage mirrors WKDL as well:
351
351
 
352
- ```
352
+ ~~~
353
353
  content = <<~DSV
354
354
  FORMAT:Wettkampfergebnisliste;7;
355
355
  ERZEUGER:Soft;1.0;mail@example.com;
@@ -363,11 +363,11 @@ DSV
363
363
  Dsv7::Parser.parse(content) do |type, payload, line_number|
364
364
  # same :format, :element, :end semantics
365
365
  end
366
- ```
366
+ ~~~
367
367
 
368
368
  VRL usage mirrors WKDL as well:
369
369
 
370
- ```
370
+ ~~~
371
371
  content = <<~DSV
372
372
  FORMAT:Vereinsergebnisliste;7;
373
373
  ERZEUGER:Soft;1.0;mail@example.com;
@@ -381,7 +381,7 @@ DSV
381
381
  Dsv7::Parser.parse(content) do |type, payload, line_number|
382
382
  # same :format, :element, :end semantics
383
383
  end
384
- ```
384
+ ~~~
385
385
 
386
386
  Errors and edge cases:
387
387
 
@@ -396,11 +396,22 @@ Errors and edge cases:
396
396
  - Tests use Minitest and live under `test/dsv7/`.
397
397
  - Version is defined in `lib/dsv7/parser/version.rb`.
398
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
+
399
410
  ## Compact ERG Example
400
411
 
401
412
  Minimal Wettkampfergebnisliste validation and parsing in one go:
402
413
 
403
- ```
414
+ ~~~
404
415
  require 'dsv7/parser'
405
416
 
406
417
  content = <<~DSV
@@ -429,6 +440,6 @@ if result.valid?
429
440
  end
430
441
  end
431
442
  else
432
- warn "Invalid ERG: #{result.errors.join('; ')}"
443
+ warn 'Invalid ERG: ' + result.errors.join('; ')
433
444
  end
434
- ```
445
+ ~~~
data/Rakefile CHANGED
@@ -3,7 +3,12 @@
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rake/testtask'
5
5
  require 'rubocop/rake_task'
6
- require 'rdoc/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
7
12
 
8
13
  Rake::TestTask.new(:test) do |t|
9
14
  t.libs << 'lib'
@@ -24,10 +29,34 @@ task lint: :rubocop
24
29
  desc 'CI: run tests and lint'
25
30
  task ci: %i[test lint]
26
31
 
27
- desc 'Generate RDoc documentation into doc/'
28
- RDoc::Task.new(:rdoc) do |rdoc|
29
- rdoc.rdoc_dir = 'doc'
30
- rdoc.main = 'README.md'
31
- rdoc.title = 'dsv7-parser'
32
- rdoc.rdoc_files.include('README.md', 'lib/**/*.rb')
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
33
62
  end
data/lib/dsv7/lex.rb CHANGED
@@ -1,18 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Lexical helpers for simple DSV7 tokens.
4
- #
5
- # - `parse_format(line)` extracts the list type and version from an exact
6
- # `FORMAT:<Listentyp>;<Version>;` line.
7
- # - `element(content)` splits an element line into its name and attributes.
8
- #
9
- # These functions are intentionally minimal and do not perform semantic checks.
10
-
11
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
12
14
  module Lex
13
15
  module_function
14
16
 
15
- # Parses a FORMAT line. Returns [list_type, version] or nil if not 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
16
20
  def parse_format(line)
17
21
  m = line.match(/^FORMAT:([^;]+);([^;]+);$/)
18
22
  return nil unless m
@@ -21,7 +25,8 @@ module Dsv7
21
25
  end
22
26
 
23
27
  # Splits an element content line into name and attributes.
24
- # Returns [name, attrs] or nil if the line is not an element line.
28
+ # @param content [String]
29
+ # @return [Array, nil] Tuple `[name, attrs]` or nil if the line is not an element line
25
30
  def element(content)
26
31
  return nil unless content.include?(':')
27
32
 
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Internal streaming engine used by `Dsv7::Parser`.
4
- #
5
- # Converts an input (path/IO/String) into a stream of parser events. It
6
- # performs the same line normalization as the validator (via Stream/IoUtil),
7
- # strips inline comments, and stops emitting at `DATEIENDE`.
8
-
9
3
  require 'stringio'
10
4
  require_relative '../stream'
11
5
  require_relative '../lex'
@@ -14,11 +8,21 @@ require_relative 'io_util'
14
8
  module Dsv7
15
9
  module Parser
16
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
17
19
  class Engine
20
+ # @api private
18
21
  def self.stream_any(input, emitter)
19
22
  new(input, emitter).stream_any
20
23
  end
21
24
 
25
+ # @api private
22
26
  def self.stream_list(input, emitter, expected_list_type)
23
27
  new(input, emitter).stream_list(expected_list_type)
24
28
  end
@@ -1,19 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Parser IO utilities.
4
- #
5
- # `to_io` converts supported inputs to an IO; `with_io` manages lifetime
6
- # and applies Stream normalization; `each_content_line` yields non‑empty,
7
- # comment‑stripped content lines with 1‑based line numbers.
8
-
9
3
  require 'stringio'
10
4
  require_relative '../stream'
11
5
 
12
6
  module Dsv7
13
7
  module Parser
14
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
+
15
18
  module_function
16
19
 
20
+ # Convert supported inputs into an IO instance.
21
+ # @param input [IO, String]
22
+ # @return [IO]
23
+ # @raise [ArgumentError] for unsupported input types
17
24
  def to_io(input)
18
25
  return input if input.respond_to?(:read)
19
26
  return File.open(input, 'rb') if input.is_a?(String) && File.file?(input)
@@ -22,6 +29,12 @@ module Dsv7
22
29
  raise ArgumentError, 'Unsupported input; pass IO, file path String, or content String'
23
30
  end
24
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]
25
38
  def with_io(input)
26
39
  close_after = input.is_a?(String) && File.file?(input)
27
40
  io = to_io(input)
@@ -32,6 +45,13 @@ module Dsv7
32
45
  io&.close if close_after
33
46
  end
34
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]
35
55
  def each_content_line(io)
36
56
  ln = 0
37
57
  io.each_line("\n") do |raw|
@@ -2,6 +2,9 @@
2
2
 
3
3
  module Dsv7
4
4
  module Parser
5
- VERSION = '7.0.1'
5
+ # Gem version for dsv7-parser
6
+ # @since 7.0.0
7
+ # @return [String]
8
+ VERSION = '7.0.2'
6
9
  end
7
10
  end