musa-dsl 0.14.32 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/README.md +5 -1
  4. data/lib/musa-dsl.rb +54 -11
  5. data/lib/musa-dsl/core-ext.rb +7 -13
  6. data/lib/musa-dsl/core-ext/array-explode-ranges.rb +15 -23
  7. data/lib/musa-dsl/core-ext/arrayfy.rb +30 -12
  8. data/lib/musa-dsl/core-ext/attribute-builder.rb +194 -0
  9. data/lib/musa-dsl/core-ext/deep-copy.rb +185 -0
  10. data/lib/musa-dsl/core-ext/dynamic-proxy.rb +44 -40
  11. data/lib/musa-dsl/core-ext/inspect-nice.rb +40 -22
  12. data/lib/musa-dsl/core-ext/smart-proc-binder.rb +108 -0
  13. data/lib/musa-dsl/core-ext/with.rb +26 -0
  14. data/lib/musa-dsl/datasets.rb +8 -3
  15. data/lib/musa-dsl/datasets/dataset.rb +3 -0
  16. data/lib/musa-dsl/datasets/delta-d.rb +12 -0
  17. data/lib/musa-dsl/datasets/e.rb +61 -0
  18. data/lib/musa-dsl/datasets/gdv.rb +51 -411
  19. data/lib/musa-dsl/datasets/gdvd.rb +179 -0
  20. data/lib/musa-dsl/datasets/helper.rb +41 -0
  21. data/lib/musa-dsl/datasets/p.rb +68 -0
  22. data/lib/musa-dsl/datasets/packed-v.rb +19 -0
  23. data/lib/musa-dsl/datasets/pdv.rb +22 -15
  24. data/lib/musa-dsl/datasets/ps.rb +113 -0
  25. data/lib/musa-dsl/datasets/score.rb +210 -0
  26. data/lib/musa-dsl/datasets/score/queriable.rb +48 -0
  27. data/lib/musa-dsl/datasets/score/render.rb +31 -0
  28. data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +160 -0
  29. data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +51 -0
  30. data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +153 -0
  31. data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +158 -0
  32. data/lib/musa-dsl/datasets/v.rb +23 -0
  33. data/lib/musa-dsl/generative.rb +5 -5
  34. data/lib/musa-dsl/generative/backboner.rb +274 -0
  35. data/lib/musa-dsl/generative/darwin.rb +102 -96
  36. data/lib/musa-dsl/generative/generative-grammar.rb +182 -187
  37. data/lib/musa-dsl/generative/markov.rb +56 -53
  38. data/lib/musa-dsl/generative/variatio.rb +234 -222
  39. data/lib/musa-dsl/logger.rb +1 -0
  40. data/lib/musa-dsl/logger/logger.rb +31 -0
  41. data/lib/musa-dsl/matrix.rb +1 -0
  42. data/lib/musa-dsl/matrix/matrix.rb +210 -0
  43. data/lib/musa-dsl/midi.rb +2 -2
  44. data/lib/musa-dsl/midi/midi-recorder.rb +54 -52
  45. data/lib/musa-dsl/midi/midi-voices.rb +183 -182
  46. data/lib/musa-dsl/music.rb +5 -5
  47. data/lib/musa-dsl/music/chord-definition.rb +54 -50
  48. data/lib/musa-dsl/music/chord-definitions.rb +13 -9
  49. data/lib/musa-dsl/music/chords.rb +236 -238
  50. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +187 -183
  51. data/lib/musa-dsl/music/scales.rb +331 -332
  52. data/lib/musa-dsl/musicxml.rb +1 -0
  53. data/lib/musa-dsl/musicxml/builder/attributes.rb +155 -0
  54. data/lib/musa-dsl/musicxml/builder/backup-forward.rb +45 -0
  55. data/lib/musa-dsl/musicxml/builder/direction.rb +322 -0
  56. data/lib/musa-dsl/musicxml/builder/helper.rb +90 -0
  57. data/lib/musa-dsl/musicxml/builder/measure.rb +137 -0
  58. data/lib/musa-dsl/musicxml/builder/note-complexities.rb +152 -0
  59. data/lib/musa-dsl/musicxml/builder/note.rb +577 -0
  60. data/lib/musa-dsl/musicxml/builder/part-group.rb +44 -0
  61. data/lib/musa-dsl/musicxml/builder/part.rb +67 -0
  62. data/lib/musa-dsl/musicxml/builder/pitched-note.rb +126 -0
  63. data/lib/musa-dsl/musicxml/builder/rest.rb +117 -0
  64. data/lib/musa-dsl/musicxml/builder/score-partwise.rb +120 -0
  65. data/lib/musa-dsl/musicxml/builder/typed-text.rb +43 -0
  66. data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +112 -0
  67. data/lib/musa-dsl/neumalang.rb +1 -1
  68. data/lib/musa-dsl/neumalang/datatypes.citrus +79 -0
  69. data/lib/musa-dsl/neumalang/neuma.citrus +165 -0
  70. data/lib/musa-dsl/neumalang/neumalang.citrus +32 -242
  71. data/lib/musa-dsl/neumalang/neumalang.rb +373 -142
  72. data/lib/musa-dsl/neumalang/process.citrus +21 -0
  73. data/lib/musa-dsl/neumalang/terminals.citrus +67 -0
  74. data/lib/musa-dsl/neumalang/vectors.citrus +23 -0
  75. data/lib/musa-dsl/neumas.rb +5 -0
  76. data/lib/musa-dsl/neumas/array-to-neumas.rb +34 -0
  77. data/lib/musa-dsl/neumas/neuma-decoder.rb +63 -0
  78. data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +57 -0
  79. data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +15 -0
  80. data/lib/musa-dsl/neumas/neumas.rb +37 -0
  81. data/lib/musa-dsl/neumas/string-to-neumas.rb +33 -0
  82. data/lib/musa-dsl/repl.rb +1 -1
  83. data/lib/musa-dsl/repl/repl.rb +103 -110
  84. data/lib/musa-dsl/sequencer.rb +1 -1
  85. data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +163 -136
  86. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +301 -286
  87. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +548 -321
  88. data/lib/musa-dsl/sequencer/base-sequencer-public.rb +198 -176
  89. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +77 -0
  90. data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +75 -0
  91. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +105 -85
  92. data/lib/musa-dsl/sequencer/timeslots.rb +34 -0
  93. data/lib/musa-dsl/series.rb +1 -1
  94. data/lib/musa-dsl/{core-ext → series}/array-to-serie.rb +1 -1
  95. data/lib/musa-dsl/series/base-series.rb +171 -168
  96. data/lib/musa-dsl/series/hash-serie-splitter.rb +134 -132
  97. data/lib/musa-dsl/series/holder-serie.rb +1 -1
  98. data/lib/musa-dsl/series/main-serie-constructors.rb +6 -1
  99. data/lib/musa-dsl/series/main-serie-operations.rb +807 -797
  100. data/lib/musa-dsl/series/proxy-serie.rb +6 -6
  101. data/lib/musa-dsl/series/queue-serie.rb +5 -5
  102. data/lib/musa-dsl/series/series.rb +2 -0
  103. data/lib/musa-dsl/transcription.rb +4 -0
  104. data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +227 -0
  105. data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +36 -0
  106. data/lib/musa-dsl/transcription/from-gdv.rb +17 -0
  107. data/lib/musa-dsl/transcription/transcription.rb +55 -0
  108. data/lib/musa-dsl/transport.rb +6 -6
  109. data/lib/musa-dsl/transport/clock.rb +26 -26
  110. data/lib/musa-dsl/transport/dummy-clock.rb +32 -30
  111. data/lib/musa-dsl/transport/external-tick-clock.rb +21 -20
  112. data/lib/musa-dsl/transport/input-midi-clock.rb +82 -80
  113. data/lib/musa-dsl/transport/timer-clock.rb +72 -71
  114. data/lib/musa-dsl/transport/timer.rb +28 -26
  115. data/lib/musa-dsl/transport/transport.rb +100 -95
  116. data/musa-dsl.gemspec +3 -3
  117. metadata +73 -24
  118. data/lib/musa-dsl/core-ext/array-apply-get.rb +0 -18
  119. data/lib/musa-dsl/core-ext/array-to-neumas.rb +0 -28
  120. data/lib/musa-dsl/core-ext/as-context-run.rb +0 -44
  121. data/lib/musa-dsl/core-ext/duplicate.rb +0 -134
  122. data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +0 -85
  123. data/lib/musa-dsl/core-ext/proc-nice.rb +0 -13
  124. data/lib/musa-dsl/core-ext/send-nice.rb +0 -21
  125. data/lib/musa-dsl/core-ext/string-to-neumas.rb +0 -27
  126. data/lib/musa-dsl/datasets/gdv-decorators.rb +0 -221
  127. data/lib/musa-dsl/generative/rules.rb +0 -282
  128. data/lib/musa-dsl/neuma.rb +0 -1
  129. data/lib/musa-dsl/neuma/neuma.rb +0 -181
@@ -1,145 +1,151 @@
1
- require 'musa-dsl/core-ext/as-context-run'
1
+ require_relative '../core-ext/with'
2
2
 
3
3
  module Musa
4
- class Darwin
5
- def initialize(&block)
6
- raise ArgumentError, 'block is needed' unless block
4
+ module Darwin
5
+ class Darwin
6
+ def initialize(&block)
7
+ raise ArgumentError, 'block is needed' unless block
7
8
 
8
- main_context = MainContext.new block
9
+ main_context = MainContext.new &block
9
10
 
10
- @measures = main_context._measures
11
- @weights = main_context._weights
12
- end
11
+ @measures = main_context._measures
12
+ @weights = main_context._weights
13
+ end
13
14
 
14
- def select(population)
15
- measured_objects = []
15
+ def select(population)
16
+ measured_objects = []
16
17
 
17
- population.each do |object|
18
- context = MeasuresEvalContext.new
18
+ population.each do |object|
19
+ context = MeasuresEvalContext.new
19
20
 
20
- context.instance_exec object, &@measures
21
- measure = context._measure
21
+ context.with object, **{}, &@measures
22
+ measure = context._measure
22
23
 
23
- measured_objects << { object: object, measure: context._measure } unless measure.died?
24
- end
24
+ measured_objects << { object: object, measure: context._measure } unless measure.died?
25
+ end
25
26
 
26
- limits = {}
27
+ limits = {}
27
28
 
28
- measured_objects.each do |measured_object|
29
- measure = measured_object[:measure]
29
+ measured_objects.each do |measured_object|
30
+ measure = measured_object[:measure]
30
31
 
31
- measure.dimensions.each do |measure_name, value|
32
- limit = limits[measure_name] ||= { min: nil, max: nil }
32
+ measure.dimensions.each do |measure_name, value|
33
+ limit = limits[measure_name] ||= { min: nil, max: nil }
33
34
 
34
- limit[:min] = value.to_f if limit[:min].nil? || limit[:min] > value
35
- limit[:max] = value.to_f if limit[:max].nil? || limit[:max] < value
35
+ limit[:min] = value.to_f if limit[:min].nil? || limit[:min] > value
36
+ limit[:max] = value.to_f if limit[:max].nil? || limit[:max] < value
36
37
 
37
- limit[:range] = limit[:max] - limit[:min]
38
+ limit[:range] = limit[:max] - limit[:min]
39
+ end
38
40
  end
39
- end
40
41
 
41
- # warn "Darwin.select: weights #{@weights}"
42
+ # warn "Darwin.select: weights #{@weights}"
43
+
44
+ measured_objects.each do |measured_object|
45
+ measure = measured_object[:measure]
42
46
 
43
- measured_objects.each do |measured_object|
44
- measure = measured_object[:measure]
47
+ measure.dimensions.each do |dimension_name, value|
48
+ limit = limits[dimension_name]
49
+ measure.normalized_dimensions[dimension_name] = (value - limit[:min]) / limit[:range]
50
+ end
45
51
 
46
- measure.dimensions.each do |dimension_name, value|
47
- limit = limits[dimension_name]
48
- measure.normalized_dimensions[dimension_name] = (value - limit[:min]) / limit[:range]
52
+ # warn "Darwin.select: #{measured_object[:object]} #{measured_object[:measure]} weight=#{measured_object[:measure].evaluate_weight(@weights).round(2)}"
49
53
  end
50
54
 
51
- # warn "Darwin.select: #{measured_object[:object]} #{measured_object[:measure]} weight=#{measured_object[:measure].evaluate_weight(@weights).round(2)}"
52
- end
55
+ measured_objects.sort! { |a, b| evaluate_weights a[:measure], b[:measure] }
53
56
 
54
- measured_objects.sort! { |a, b| evaluate_weights a[:measure], b[:measure] }
57
+ measured_objects.collect { |measured_object| measured_object[:object] }
58
+ end
55
59
 
56
- measured_objects.collect { |measured_object| measured_object[:object] }
57
- end
60
+ def evaluate_weights(measure_a, measure_b)
61
+ measure_b.evaluate_weight(@weights) <=> measure_a.evaluate_weight(@weights)
62
+ end
58
63
 
59
- def evaluate_weights(measure_a, measure_b)
60
- measure_b.evaluate_weight(@weights) <=> measure_a.evaluate_weight(@weights)
61
- end
64
+ class MainContext
65
+ include Musa::Extension::With
62
66
 
63
- class MainContext
64
- attr_reader :_measures, :_weights
67
+ attr_reader :_measures, :_weights
65
68
 
66
- def initialize(block)
67
- @_weights = {}
68
- _as_context_run block
69
- end
69
+ def initialize(&block)
70
+ @_weights = {}
71
+ with &block
72
+ end
70
73
 
71
- def measures(&block)
72
- @_measures = block
73
- end
74
+ def measures(&block)
75
+ @_measures = block
76
+ end
74
77
 
75
- def weight(**feature_or_dimension_weights)
76
- feature_or_dimension_weights.each do |name, value|
77
- @_weights[name] = value
78
+ def weight(**feature_or_dimension_weights)
79
+ feature_or_dimension_weights.each do |name, value|
80
+ @_weights[name] = value
81
+ end
78
82
  end
79
83
  end
80
- end
81
84
 
82
- class MeasuresEvalContext
83
- def initialize
84
- @_features = {}
85
- @_dimensions = {}
86
- @_died = false
87
- end
85
+ class MeasuresEvalContext
86
+ include Musa::Extension::With
88
87
 
89
- def _measure
90
- Measure.new @_features, @_dimensions, @_died
91
- end
88
+ def initialize
89
+ @_features = {}
90
+ @_dimensions = {}
91
+ @_died = false
92
+ end
92
93
 
93
- def feature(feature_name)
94
- @_features[feature_name] = true
95
- end
94
+ def _measure
95
+ Measure.new @_features, @_dimensions, @_died
96
+ end
96
97
 
97
- def dimension(dimension_name, value)
98
- @_dimensions[dimension_name] = value
99
- end
98
+ def feature(feature_name)
99
+ @_features[feature_name] = true
100
+ end
100
101
 
101
- def die
102
- @_died = true
103
- end
102
+ def dimension(dimension_name, value)
103
+ @_dimensions[dimension_name] = value
104
+ end
105
+
106
+ def die
107
+ @_died = true
108
+ end
104
109
 
105
- def died?
106
- @_died
110
+ def died?
111
+ @_died
112
+ end
107
113
  end
108
- end
109
114
 
110
- class Measure
111
- attr_reader :features, :dimensions, :normalized_dimensions
115
+ class Measure
116
+ attr_reader :features, :dimensions, :normalized_dimensions
112
117
 
113
- def initialize(features, dimensions, died)
114
- @features = features
115
- @dimensions = dimensions
116
- @died = died
118
+ def initialize(features, dimensions, died)
119
+ @features = features
120
+ @dimensions = dimensions
121
+ @died = died
117
122
 
118
- @normalized_dimensions = {}
119
- end
123
+ @normalized_dimensions = {}
124
+ end
120
125
 
121
- def died?
122
- @died
123
- end
126
+ def died?
127
+ @died
128
+ end
124
129
 
125
- def evaluate_weight(weights)
126
- total = 0.0
130
+ def evaluate_weight(weights)
131
+ total = 0.0
127
132
 
128
- unless @died
129
- weights.each do |name, weight|
130
- total += @normalized_dimensions[name] * weight if @normalized_dimensions.key? name
131
- total += weight if @features[name]
133
+ unless @died
134
+ weights.each do |name, weight|
135
+ total += @normalized_dimensions[name] * weight if @normalized_dimensions.key? name
136
+ total += weight if @features[name]
137
+ end
132
138
  end
139
+
140
+ total
133
141
  end
134
142
 
135
- total
136
- end
143
+ def inspect
144
+ "Measure features=#{@features.collect { |k, _v| k }} dimensions=#{@normalized_dimensions.collect { |k, v| [k, [@dimensions[k].round(5), v.round(2)]] }.to_h}"
145
+ end
137
146
 
138
- def inspect
139
- "Measure features=#{@features.collect { |k, _v| k }} dimensions=#{@normalized_dimensions.collect { |k, v| [k, [@dimensions[k].round(5), v.round(2)]] }.to_h}"
147
+ alias to_s inspect
140
148
  end
141
-
142
- alias to_s inspect
143
149
  end
144
150
  end
145
151
  end
@@ -1,14 +1,19 @@
1
1
  module Musa
2
2
  module GenerativeGrammar
3
+ extend self
3
4
 
4
5
  def N(content = nil, **attributes, &block)
5
6
  if block_given? && content.nil?
6
- BlockNode.new(attributes, &block)
7
+ Implementation::BlockNode.new(attributes, &block)
7
8
  else
8
- FinalNode.new(content, attributes)
9
+ Implementation::FinalNode.new(content, attributes)
9
10
  end
10
11
  end
11
12
 
13
+ def PN
14
+ Implementation::ProxyNode.new
15
+ end
16
+
12
17
  class OptionElement
13
18
  attr_reader :content, :attributes
14
19
 
@@ -18,277 +23,267 @@ module Musa
18
23
  end
19
24
  end
20
25
 
21
- class Node
22
- def or(other)
23
- OrNode.new(self, other)
24
- end
26
+ module Implementation
27
+ class Node
28
+ def or(other)
29
+ OrNode.new(self, other)
30
+ end
25
31
 
26
- alias_method :|, :or
32
+ alias_method :|, :or
27
33
 
28
- def repeat(exactly = nil, min: nil, max: nil)
29
- raise ArgumentError, 'Only exactly value or min/max values are allowed' if exactly && (min || max)
34
+ def repeat(exactly = nil, min: nil, max: nil)
35
+ raise ArgumentError, 'Only exactly value or min/max values are allowed' if exactly && (min || max)
30
36
 
31
- min = max = exactly if exactly
37
+ min = max = exactly if exactly
32
38
 
33
- if min && min > 0
34
- pre = self
39
+ if min && min > 0
40
+ pre = self
35
41
 
36
- (min - 1).times do
37
- pre += self
42
+ (min - 1).times do
43
+ pre += self
44
+ end
38
45
  end
39
- end
40
46
 
41
- if pre && max == min
42
- pre
43
- elsif pre && max > min
44
- pre + RepeatNode.new(self, max - min)
45
- else
46
- RepeatNode.new(self, max)
47
+ if pre && max == min
48
+ pre
49
+ elsif pre && max > min
50
+ pre + RepeatNode.new(self, max - min)
51
+ else
52
+ RepeatNode.new(self, max)
53
+ end
47
54
  end
48
- end
49
55
 
50
- def limit(attribute = nil, after_collect_operation = nil, comparison_method = nil, comparison_value = nil, &block)
51
- raise ArgumentError, 'Cannot use simplified arguments and yield block at the same time' if (attribute || after_collect_operation || comparison_method || comparison_value) && @block
56
+ def limit(attribute = nil, after_collect_operation = nil, comparison_method = nil, comparison_value = nil, &block)
57
+ raise ArgumentError, 'Cannot use simplified arguments and yield block at the same time' if (attribute || after_collect_operation || comparison_method || comparison_value) && @block
52
58
 
53
- block ||= generate_simple_condition_block(attribute, after_collect_operation, comparison_method, comparison_value)
59
+ block ||= generate_simple_condition_block(attribute, after_collect_operation, comparison_method, comparison_value)
54
60
 
55
- ConditionNode.new(self, &block)
56
- end
61
+ ConditionNode.new(self, &block)
62
+ end
57
63
 
58
- def next(other)
59
- NextNode.new(self, other)
60
- end
64
+ def next(other)
65
+ NextNode.new(self, other)
66
+ end
61
67
 
62
- alias_method :+, :next
68
+ alias_method :+, :next
63
69
 
64
- def options(attribute = nil,
65
- after_collect_operation = nil,
66
- comparison_method = nil,
67
- comparison_value = nil,
68
- raw: nil,
69
- content: nil,
70
- &condition)
70
+ def options(attribute = nil,
71
+ after_collect_operation = nil,
72
+ comparison_method = nil,
73
+ comparison_value = nil,
74
+ raw: nil,
75
+ content: nil,
76
+ &condition)
71
77
 
72
- raise ArgumentError, 'Cannot use simplified arguments and yield block at the same time' if (attribute || after_collect_operation || comparison_method || comparison_value) && @condition
73
- raise ArgumentError, 'Cannot use raw: true and content: option at the same time' if raw && content
78
+ raise ArgumentError, 'Cannot use simplified arguments and yield block at the same time' if (attribute || after_collect_operation || comparison_method || comparison_value) && @condition
79
+ raise ArgumentError, 'Cannot use raw: true and content: option at the same time' if raw && content
74
80
 
75
- raw ||= false
76
- content ||= :itself
81
+ raw ||= false
82
+ content ||= :itself
77
83
 
78
- condition ||= generate_simple_condition_block(attribute, after_collect_operation, comparison_method, comparison_value)
84
+ condition ||= generate_simple_condition_block(attribute, after_collect_operation, comparison_method, comparison_value)
79
85
 
80
- if raw
81
- _options(&condition)
82
- else
83
- _options(&condition).collect { |o| o.collect(&:content).send(content) }
86
+ if raw
87
+ _options(&condition)
88
+ else
89
+ _options(&condition).collect { |o| o.collect(&:content).send(content) }
90
+ end
84
91
  end
85
- end
86
92
 
87
- def size
88
- options.size
89
- end
93
+ def size
94
+ options.size
95
+ end
90
96
 
91
- alias_method :length, :size
97
+ alias_method :length, :size
92
98
 
93
- def [](index)
94
- options[index].to_serie.to_node
95
- end
99
+ def [](index)
100
+ options[index].to_serie.to_node
101
+ end
96
102
 
97
- def to_serie(flatten: nil, &condition)
98
- flatten ||= true
103
+ def to_serie(flatten: nil, &condition)
104
+ flatten ||= true
99
105
 
100
- serie = _options(&condition).collect { |o| o.collect(&:content) }.to_serie(of_series: true).merge
101
- serie = serie.flatten if flatten
106
+ serie = _options(&condition).collect { |o| o.collect(&:content) }.to_serie(of_series: true).merge
107
+ serie = serie.flatten if flatten
102
108
 
103
- serie.prototype
104
- end
109
+ serie.prototype
110
+ end
105
111
 
106
- alias_method :s, :to_serie
112
+ alias_method :s, :to_serie
107
113
 
108
- def _options(parent: nil, &condition)
109
- raise NotImplementedError
110
- end
114
+ def _options(parent: nil, &condition)
115
+ raise NotImplementedError
116
+ end
111
117
 
112
- protected
118
+ protected
113
119
 
114
- def generate_simple_condition_block(attribute = nil,
115
- after_collect_operation = nil,
116
- comparison_method = nil,
117
- comparison_value = nil)
120
+ def generate_simple_condition_block(attribute = nil,
121
+ after_collect_operation = nil,
122
+ comparison_method = nil,
123
+ comparison_value = nil)
118
124
 
119
- if attribute && after_collect_operation && comparison_method && comparison_value
120
- proc do |o|
121
- o.collect { |_| _.attributes[attribute] }
122
- .send(after_collect_operation)
123
- .send(comparison_method, comparison_value)
125
+ if attribute && after_collect_operation && comparison_method && comparison_value
126
+ proc do |o|
127
+ o.collect { |_| _.attributes[attribute] }
128
+ .send(after_collect_operation)
129
+ .send(comparison_method, comparison_value)
130
+ end
124
131
  end
125
132
  end
126
133
  end
127
- end
128
134
 
129
- private_constant :Node
135
+ class ProxyNode < Node
136
+ attr_accessor :node
130
137
 
131
- class ProxyNode < Node
132
- attr_accessor :node
133
-
134
- def _options(parent: nil, &condition)
135
- @node._options parent: parent, &condition
138
+ def _options(parent: nil, &condition)
139
+ @node._options parent: parent, &condition
140
+ end
136
141
  end
137
- end
138
142
 
139
- class FinalNode < Node
140
- attr_reader :content
141
- attr_reader :attributes
143
+ class FinalNode < Node
144
+ attr_reader :content
145
+ attr_reader :attributes
142
146
 
143
- def initialize(content, attributes)
144
- super()
145
- @element = OptionElement.new(content, attributes)
146
- end
147
+ def initialize(content, attributes)
148
+ super()
149
+ @element = OptionElement.new(content, attributes)
150
+ end
147
151
 
148
- def _options(parent: nil, &condition)
149
- parent ||= []
152
+ def _options(parent: nil, &condition)
153
+ parent ||= []
150
154
 
151
- if block_given?
152
- if yield(parent + [@element])
153
- [[@element]]
155
+ if block_given?
156
+ if yield(parent + [@element])
157
+ [[@element]]
158
+ else
159
+ []
160
+ end
154
161
  else
155
- []
162
+ [[@element]]
156
163
  end
157
- else
158
- [[@element]]
159
164
  end
160
165
  end
161
- end
162
-
163
- private_constant :FinalNode
164
166
 
165
- class BlockNode < Node
166
- def initialize(attributes, &block)
167
- @attributes = attributes
168
- @block = block
169
- end
167
+ class BlockNode < Node
168
+ def initialize(attributes, &block)
169
+ @attributes = attributes
170
+ @block = block
171
+ end
170
172
 
171
- def _options(parent: nil, &condition)
172
- parent ||= []
173
+ def _options(parent: nil, &condition)
174
+ parent ||= []
173
175
 
174
- element = @block.call(parent, @attributes)
175
- element = OptionElement.new(element, @attributes) unless element.is_a?(OptionElement)
176
+ element = @block.call(parent, @attributes)
177
+ element = OptionElement.new(element, @attributes) unless element.is_a?(OptionElement)
176
178
 
177
- if block_given?
178
- if yield(parent + [element], @attributes)
179
- [[element]]
179
+ if block_given?
180
+ if yield(parent + [element], @attributes)
181
+ [[element]]
182
+ else
183
+ []
184
+ end
180
185
  else
181
- []
186
+ [[element]]
182
187
  end
183
- else
184
- [[element]]
185
188
  end
186
189
  end
187
- end
188
190
 
189
- private_constant :BlockNode
191
+ class ConditionNode < Node
192
+ def initialize(node, &block)
193
+ @node = node
194
+ @block = block
195
+ end
190
196
 
191
- class ConditionNode < Node
192
- def initialize(node, &block)
193
- @node = node
194
- @block = block
195
- end
197
+ def _options(parent: nil, &condition)
198
+ parent ||= []
196
199
 
197
- def _options(parent: nil, &condition)
198
- parent ||= []
200
+ r = []
199
201
 
200
- r = []
202
+ @node._options(parent: parent, &condition).each do |node_option|
203
+ r << node_option if (!block_given? || yield(parent + node_option)) && @block.call(parent + node_option)
204
+ end
201
205
 
202
- @node._options(parent: parent, &condition).each do |node_option|
203
- r << node_option if (!block_given? || yield(parent + node_option)) && @block.call(parent + node_option)
206
+ r
204
207
  end
205
-
206
- r
207
208
  end
208
- end
209
209
 
210
- private_constant :ConditionNode
210
+ class OrNode < Node
211
+ def initialize(node1, node2)
212
+ @node1 = node1
213
+ @node2 = node2
214
+ super()
215
+ end
211
216
 
212
- class OrNode < Node
213
- def initialize(node1, node2)
214
- @node1 = node1
215
- @node2 = node2
216
- super()
217
- end
217
+ def _options(parent: nil, &condition)
218
+ parent ||= []
218
219
 
219
- def _options(parent: nil, &condition)
220
- parent ||= []
220
+ r = []
221
221
 
222
- r = []
222
+ @node1._options(parent: parent, &condition).each do |node_option|
223
+ r << node_option if !block_given? || yield(parent + node_option)
224
+ end
223
225
 
224
- @node1._options(parent: parent, &condition).each do |node_option|
225
- r << node_option if !block_given? || yield(parent + node_option)
226
- end
226
+ @node2._options(parent: parent, &condition).each do |node_option|
227
+ r << node_option if !block_given? || yield(parent + node_option)
228
+ end
227
229
 
228
- @node2._options(parent: parent, &condition).each do |node_option|
229
- r << node_option if !block_given? || yield(parent + node_option)
230
+ r
230
231
  end
231
-
232
- r
233
232
  end
234
- end
235
233
 
236
- private_constant :OrNode
237
-
238
- class NextNode < Node
239
- def initialize(node, after)
240
- @node = node
241
- @after = after
242
- super()
243
- end
234
+ class NextNode < Node
235
+ def initialize(node, after)
236
+ @node = node
237
+ @after = after
238
+ super()
239
+ end
244
240
 
245
- def _options(parent: nil, &condition)
246
- parent ||= []
241
+ def _options(parent: nil, &condition)
242
+ parent ||= []
247
243
 
248
- r = []
249
- @node._options(parent: parent, &condition).each do |node_option|
250
- @after._options(parent: parent + node_option, &condition).each do |after_option|
251
- r << node_option + after_option unless after_option.empty?
244
+ r = []
245
+ @node._options(parent: parent, &condition).each do |node_option|
246
+ @after._options(parent: parent + node_option, &condition).each do |after_option|
247
+ r << node_option + after_option unless after_option.empty?
248
+ end
252
249
  end
250
+ r
253
251
  end
254
- r
255
252
  end
256
- end
257
-
258
- private_constant :NextNode
259
253
 
260
- class RepeatNode < Node
261
- def initialize(node, max = nil)
262
- @node = node
263
- @max = max
254
+ class RepeatNode < Node
255
+ def initialize(node, max = nil)
256
+ @node = node
257
+ @max = max
264
258
 
265
- super()
266
- end
259
+ super()
260
+ end
267
261
 
268
- def _options(parent: nil, depth: nil, &condition)
269
- parent ||= []
270
- depth ||= 0
262
+ def _options(parent: nil, depth: nil, &condition)
263
+ parent ||= []
264
+ depth ||= 0
271
265
 
272
- r = []
266
+ r = []
273
267
 
274
- if @max.nil? || depth < @max
275
- node_options = @node._options(parent: parent, &condition)
268
+ if @max.nil? || depth < @max
269
+ node_options = @node._options(parent: parent, &condition)
276
270
 
277
- node_options.each do |node_option|
278
- r << node_option
271
+ node_options.each do |node_option|
272
+ r << node_option
279
273
 
280
- node_suboptions = _options(parent: parent + node_option, depth: depth + 1, &condition)
274
+ node_suboptions = _options(parent: parent + node_option, depth: depth + 1, &condition)
281
275
 
282
- node_suboptions.each do |node_suboption|
283
- r << node_option + node_suboption
276
+ node_suboptions.each do |node_suboption|
277
+ r << node_option + node_suboption
278
+ end
284
279
  end
285
280
  end
286
- end
287
281
 
288
- r
282
+ r
283
+ end
289
284
  end
290
285
  end
291
286
 
292
- private_constant :RepeatNode
287
+ private_constant :Implementation
293
288
  end
294
289
  end