sportdb-quick 0.5.3 → 0.7.0

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.
data/lib/sportdb/quick.rb CHANGED
@@ -1,8 +1,6 @@
1
- require 'sportdb/structs' # deps: score-foramts
2
- # season-formats
3
- # alphabets
4
- require 'sportdb/parser' # deps: cocos
5
- # season-formats
1
+ require 'sportdb/parser' # deps: cocos, racc
2
+
3
+ require 'season-formats'
6
4
 
7
5
 
8
6
 
@@ -17,21 +15,26 @@ end
17
15
  ## our own code
18
16
  require_relative 'quick/version'
19
17
 
20
- ## "generic" outline readers, documents & more
21
- ##
22
- ## todo/check - move outline reader upstream to cocos - why? why not?
23
- ## use read_outline(), parse_outline() - why? why not?
24
- require_relative 'quick/outline_reader'
25
- require_relative 'quick/outline'
26
-
27
18
  ## match & league machinery
28
- require_relative 'quick/match_parser'
19
+ require_relative 'quick/match_tree'
20
+ require_relative 'quick/match_tree-helpers'
29
21
 
30
- require_relative 'quick/quick_league_outline'
31
- require_relative 'quick/quick_match_reader'
22
+ require_relative 'quick/match_tree/match' ## ("inline") structs
23
+ require_relative 'quick/match_tree/goal'
24
+ require_relative 'quick/match_tree/round'
25
+ require_relative 'quick/match_tree/group'
32
26
 
27
+ require_relative 'quick/match_tree_on/on_group_def'
28
+ require_relative 'quick/match_tree_on/on_round_def'
29
+ require_relative 'quick/match_tree_on/on_round_outline'
30
+ require_relative 'quick/match_tree_on/on_date_header'
31
+ require_relative 'quick/match_tree_on/on_match_line'
32
+ require_relative 'quick/match_tree_on/on_goal_line'
33
33
 
34
34
 
35
- puts SportDb::Module::Quick.banner # say hello
35
+ require_relative 'quick/match_parser'
36
+ require_relative 'quick/quick_match_reader'
36
37
 
37
38
 
39
+
40
+ puts SportDb::Module::Quick.banner # say hello
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-quick
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-24 00:00:00.000000000 Z
11
+ date: 2026-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-parser
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.5.4
19
+ version: 0.7.0
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
- version: 0.5.4
26
+ version: 0.7.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: sportdb-structs
28
+ name: season-formats
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.5.0
33
+ version: 0.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
- version: 0.5.0
40
+ version: 0.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: logutils
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -101,9 +101,18 @@ files:
101
101
  - Rakefile
102
102
  - lib/sportdb/quick.rb
103
103
  - lib/sportdb/quick/match_parser.rb
104
- - lib/sportdb/quick/outline.rb
105
- - lib/sportdb/quick/outline_reader.rb
106
- - lib/sportdb/quick/quick_league_outline.rb
104
+ - lib/sportdb/quick/match_tree-helpers.rb
105
+ - lib/sportdb/quick/match_tree.rb
106
+ - lib/sportdb/quick/match_tree/goal.rb
107
+ - lib/sportdb/quick/match_tree/group.rb
108
+ - lib/sportdb/quick/match_tree/match.rb
109
+ - lib/sportdb/quick/match_tree/round.rb
110
+ - lib/sportdb/quick/match_tree_on/on_date_header.rb
111
+ - lib/sportdb/quick/match_tree_on/on_goal_line.rb
112
+ - lib/sportdb/quick/match_tree_on/on_group_def.rb
113
+ - lib/sportdb/quick/match_tree_on/on_match_line.rb
114
+ - lib/sportdb/quick/match_tree_on/on_round_def.rb
115
+ - lib/sportdb/quick/match_tree_on/on_round_outline.rb
107
116
  - lib/sportdb/quick/quick_match_reader.rb
108
117
  - lib/sportdb/quick/version.rb
109
118
  homepage: https://github.com/sportdb/sport.db
@@ -1,96 +0,0 @@
1
-
2
- module SportDb
3
-
4
- ###
5
- # add a simple Outline convenience class
6
- # for processing OUtlines with OUtlineReader
7
- # rename to simply Outline - why? why not?
8
- # todo - add more processing options - why? why not?
9
-
10
- class Outline
11
- def self.read( path )
12
- nodes = OutlineReader.read( path )
13
- new( nodes )
14
- end
15
-
16
- def self.parse( txt )
17
- nodes = OutlineReader.parse( txt )
18
- new( nodes )
19
- end
20
-
21
-
22
- def initialize( nodes )
23
- @nodes = nodes
24
- end
25
-
26
- def each_para( &blk )
27
- ## note: every (new) read call - resets errors list to empty
28
- ### @errors = []
29
-
30
- ## process nodes
31
- h1 = nil
32
- h2 = nil
33
- orphans = 0 ## track paragraphs's with no heading
34
-
35
- @nodes.each do |node|
36
- type = node[0]
37
-
38
- if type == :h1
39
- h1 = node[1] ## get heading text
40
- puts " = Heading 1 >#{node[1]}<"
41
- elsif type == :h2
42
- if h1.nil?
43
- puts "!! WARN - no heading for subheading; skipping processing"
44
- next
45
- end
46
- h2 = node[1] ## get heading text
47
- puts " == Heading 2 >#{node[1]}<"
48
- elsif type == :p
49
- if h1.nil?
50
- orphans += 1 ## only warn once
51
- puts "!! WARN - no heading for #{orphans} text paragraph(s); skipping parse"
52
- next
53
- end
54
-
55
- lines = node[1]
56
- blk.call( lines )
57
- else
58
- pp node
59
- raise ArgumentError, "unsupported (node) type >#{type}<"
60
- end
61
- end # each node
62
- end # each_para
63
- alias_method :each_paragraph, :each_para
64
-
65
-
66
- ## get all para(graphs) as text (not array of lines)
67
- ## make default - why? why not?
68
- #
69
- # design - or wrap lines into a Para class
70
- # with properties lines and text
71
- # and such - why? why not?
72
- # downside - might be overkill/overengineered
73
- # just use simple txt as string (buffer) for all - why? why not?
74
- ##
75
- ## hacky alternative - add a to_text or text method to string and array - why? why not?
76
-
77
-
78
- def each_para_text( &blk ) ## or use each_text or ? - why? why not=
79
- each_para do |lines|
80
- txt = lines.reduce( String.new ) do |mem,line|
81
- mem << line; mem << "\n"; mem
82
- end
83
- blk.call( txt )
84
- end
85
- end
86
- end # class Outline
87
-
88
-
89
-
90
- ###
91
- # add alternate alias - why? why not?
92
- QuickMatchOutline = Outline
93
-
94
-
95
- end ## module SportDb
96
-
@@ -1,98 +0,0 @@
1
-
2
-
3
- module SportDb
4
-
5
-
6
- class OutlineReader
7
-
8
- def self.debug=(value) @@debug = value; end
9
- def self.debug?() @@debug ||= false; end
10
- def debug?() self.class.debug?; end
11
-
12
-
13
-
14
- def self.read( path ) ## use - rename to read_file or from_file etc. - why? why not?
15
- txt = File.open( path, 'r:utf-8' ) {|f| f.read }
16
- parse( txt )
17
- end
18
-
19
- def self.parse( txt )
20
- new( txt ).parse
21
- end
22
-
23
- def initialize( txt )
24
- @txt = txt
25
- end
26
-
27
- ## note: skip "decorative" only heading e.g. ========
28
- ## todo/check: find a better name e.g. HEADING_EMPTY_RE or HEADING_LINE_RE or ???
29
- HEADING_BLANK_RE = %r{\A
30
- ={1,}
31
- \z}x
32
-
33
- ## note: like in wikimedia markup (and markdown) all optional trailing ==== too
34
- HEADING_RE = %r{\A
35
- (?<marker>={1,}) ## 1. leading ======
36
- [ ]*
37
- (?<text>[^=]+) ## 2. text (note: for now no "inline" = allowed)
38
- [ ]*
39
- =* ## 3. (optional) trailing ====
40
- \z}x
41
-
42
- def parse
43
- outline=[] ## outline structure
44
- start_para = true ## start new para(graph) on new text line?
45
-
46
- @txt.each_line do |line|
47
- line = line.strip ## todo/fix: keep leading and trailing spaces - why? why not?
48
-
49
- if line.empty? ## todo/fix: keep blank line nodes?? and just remove comments and process headings?! - why? why not?
50
- start_para = true
51
- next
52
- end
53
-
54
- break if line == '__END__'
55
-
56
- next if line.start_with?( '#' ) ## skip comments too
57
- ## strip inline (until end-of-line) comments too
58
- ## e.g Eupen | KAS Eupen ## [de]
59
- ## => Eupen | KAS Eupen
60
- ## e.g bq Bonaire, BOE # CONCACAF
61
- ## => bq Bonaire, BOE
62
- line = line.sub( /#.*/, '' ).strip
63
- pp line if debug?
64
-
65
- ## todo/check: also use heading blank as paragraph "breaker" or treat it like a comment ?? - why? why not?
66
- next if HEADING_BLANK_RE.match( line ) # skip "decorative" only heading e.g. ========
67
-
68
- ## note: like in wikimedia markup (and markdown) all optional trailing ==== too
69
- if m=HEADING_RE.match( line )
70
- start_para = true
71
-
72
- heading_marker = m[:marker]
73
- heading_level = heading_marker.length ## count number of = for heading level
74
- heading = m[:text].strip
75
-
76
- puts "heading #{heading_level} >#{heading}<" if debug?
77
- outline << [:"h#{heading_level}", heading]
78
- else ## assume it's a (plain/regular) text line
79
- if start_para
80
- outline << [:p, [line]]
81
- start_para = false
82
- else
83
- node = outline[-1] ## get last entry
84
- if node[0] == :p ## assert it's a p(aragraph) node!!!
85
- node[1] << line ## add line to p(aragraph)
86
- else
87
- puts "!! ERROR - invalid outline state / format - expected p(aragraph) node; got:"
88
- pp node
89
- exit 1
90
- end
91
- end
92
- end
93
- end
94
- outline
95
- end # method read
96
- end # class OutlineReader
97
-
98
- end # module SportDb
@@ -1,123 +0,0 @@
1
-
2
-
3
- module SportDb
4
-
5
- ## shared "higher-level" outline reader
6
- ### quick version WITHOUT any (database) validation/mapping/normalization !!!
7
-
8
-
9
- class QuickLeagueOutline
10
-
11
- def self.read( path )
12
- nodes = OutlineReader.read( path )
13
- new( nodes )
14
- end
15
-
16
- def self.parse( txt )
17
- nodes = OutlineReader.parse( txt )
18
- new( nodes )
19
- end
20
-
21
-
22
-
23
- def initialize( nodes )
24
- @nodes = nodes
25
- end
26
-
27
-
28
- ###
29
- # use Section struct for easier access - why? why not?
30
- ## e.g. sec.league instead of sec[:league] etc.
31
-
32
- Section = Struct.new( :league, :season, :stage, :lines ) do
33
- def text ## for alternate line access (all-in-text string)
34
- txt = lines.reduce( String.new ) do |mem,line|
35
- mem << line; mem << "\n"; mem
36
- end
37
- txt
38
- end
39
- end
40
-
41
- def each_sec( &blk )
42
- @secs ||= _parse
43
-
44
- @secs.each do |sec|
45
- blk.call( sec )
46
- end
47
- end
48
- alias_method :each_section, :each_sec
49
-
50
-
51
- def _parse
52
- secs=[] # sec(tion)s
53
- @nodes.each do |node|
54
- if node[0] == :h1
55
- ## check for league (and stage) and season
56
- heading = node[1]
57
- values = _split_league( heading )
58
- if m=values[0].match( LEAGUE_SEASON_HEADING_RE )
59
- puts "league >#{m[:league]}<, season >#{m[:season]}<"
60
-
61
- secs << Section.new( league: m[:league],
62
- season: m[:season],
63
- stage: values[1], ## note: defaults to nil if not present
64
- lines: []
65
- )
66
- else
67
- puts "** !!! ERROR - cannot match league and season in heading; season missing?"
68
- pp heading
69
- exit 1
70
- end
71
- elsif node[0] == :h2
72
- ## todo/check - make sure parsed h1 first
73
- heading = node[1]
74
- ## note - reuse league, season from h1
75
- secs << Section.new( league: secs[-1].league,
76
- season: secs[-1].season,
77
- stage: heading,
78
- lines: []
79
- )
80
- elsif node[0] == :p ## paragraph with (text) lines
81
- lines = node[1]
82
- ## note: skip lines if no heading seen
83
- if secs.empty?
84
- puts "** !!! WARN - skipping lines (no heading):"
85
- pp lines
86
- else
87
- ## todo/check: unroll paragraphs into lines or pass along paragraphs - why? why not?
88
- ## add paragraphs not unrolled lines - why? why not?
89
- secs[-1].lines += lines
90
- end
91
- else
92
- puts "** !!! ERROR - unknown line type; for now only heading 1 for leagues supported; sorry:"
93
- pp node
94
- exit 1
95
- end
96
- end
97
- secs
98
- end # method _parse
99
-
100
-
101
- ## split into league + season
102
- ## e.g. Österr. Bundesliga 2015/16 ## or 2015-16
103
- ## World Cup 2018
104
- LEAGUE_SEASON_HEADING_RE = %r{^
105
- (?<league>.+?) ## non-greedy
106
- \s+
107
- (?<season>\d{4}
108
- (?:[\/-]\d{1,4})? ## optional 2nd year in season
109
- )
110
- $}x
111
-
112
- def _split_league( str ) ## todo/check: rename to parse_league(s) - why? why not?
113
- ## split into league / stage / ... e.g.
114
- ## => Österr. Bundesliga 2018/19, Regular Season
115
- ## => Österr. Bundesliga 2018/19, Championship Round
116
- ## etc.
117
- ## note limit split to two parts only!!!!
118
- values = str.split( /[,<>‹›]/, 2 ) ## note: allow , > < or › ‹ for now
119
- values = values.map { |value| value.strip } ## remove all whitespaces
120
- values
121
- end
122
- end # class QuickLeagueOutline
123
- end # module SportDb