musicality 0.1.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.
Files changed (141) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +47 -0
  8. data/Rakefile +65 -0
  9. data/bin/midify +78 -0
  10. data/examples/hip.rb +32 -0
  11. data/examples/missed_connection.rb +26 -0
  12. data/examples/song1.rb +33 -0
  13. data/examples/song2.rb +32 -0
  14. data/lib/musicality/errors.rb +9 -0
  15. data/lib/musicality/notation/conversion/change_conversion.rb +19 -0
  16. data/lib/musicality/notation/conversion/measure_note_map.rb +40 -0
  17. data/lib/musicality/notation/conversion/measured_score_conversion.rb +70 -0
  18. data/lib/musicality/notation/conversion/measured_score_converter.rb +95 -0
  19. data/lib/musicality/notation/conversion/note_time_converter.rb +68 -0
  20. data/lib/musicality/notation/conversion/tempo_conversion.rb +25 -0
  21. data/lib/musicality/notation/conversion/unmeasured_score_conversion.rb +47 -0
  22. data/lib/musicality/notation/conversion/unmeasured_score_converter.rb +64 -0
  23. data/lib/musicality/notation/model/articulations.rb +13 -0
  24. data/lib/musicality/notation/model/change.rb +62 -0
  25. data/lib/musicality/notation/model/dynamics.rb +12 -0
  26. data/lib/musicality/notation/model/link.rb +73 -0
  27. data/lib/musicality/notation/model/meter.rb +54 -0
  28. data/lib/musicality/notation/model/meters.rb +9 -0
  29. data/lib/musicality/notation/model/note.rb +120 -0
  30. data/lib/musicality/notation/model/part.rb +54 -0
  31. data/lib/musicality/notation/model/pitch.rb +163 -0
  32. data/lib/musicality/notation/model/pitches.rb +21 -0
  33. data/lib/musicality/notation/model/program.rb +53 -0
  34. data/lib/musicality/notation/model/score.rb +132 -0
  35. data/lib/musicality/notation/packing/change_packing.rb +46 -0
  36. data/lib/musicality/notation/packing/part_packing.rb +31 -0
  37. data/lib/musicality/notation/packing/program_packing.rb +16 -0
  38. data/lib/musicality/notation/packing/score_packing.rb +108 -0
  39. data/lib/musicality/notation/parsing/articulation_parsing.rb +264 -0
  40. data/lib/musicality/notation/parsing/articulation_parsing.treetop +59 -0
  41. data/lib/musicality/notation/parsing/convenience_methods.rb +74 -0
  42. data/lib/musicality/notation/parsing/duration_nodes.rb +21 -0
  43. data/lib/musicality/notation/parsing/duration_parsing.rb +205 -0
  44. data/lib/musicality/notation/parsing/duration_parsing.treetop +25 -0
  45. data/lib/musicality/notation/parsing/link_nodes.rb +35 -0
  46. data/lib/musicality/notation/parsing/link_parsing.rb +270 -0
  47. data/lib/musicality/notation/parsing/link_parsing.treetop +33 -0
  48. data/lib/musicality/notation/parsing/meter_parsing.rb +190 -0
  49. data/lib/musicality/notation/parsing/meter_parsing.treetop +29 -0
  50. data/lib/musicality/notation/parsing/note_node.rb +40 -0
  51. data/lib/musicality/notation/parsing/note_parsing.rb +229 -0
  52. data/lib/musicality/notation/parsing/note_parsing.treetop +28 -0
  53. data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.rb +289 -0
  54. data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.treetop +29 -0
  55. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +64 -0
  56. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.treetop +17 -0
  57. data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.rb +86 -0
  58. data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.treetop +20 -0
  59. data/lib/musicality/notation/parsing/numbers/positive_float_parsing.rb +503 -0
  60. data/lib/musicality/notation/parsing/numbers/positive_float_parsing.treetop +33 -0
  61. data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.rb +95 -0
  62. data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.treetop +19 -0
  63. data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.rb +84 -0
  64. data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.treetop +19 -0
  65. data/lib/musicality/notation/parsing/parseable.rb +30 -0
  66. data/lib/musicality/notation/parsing/pitch_node.rb +23 -0
  67. data/lib/musicality/notation/parsing/pitch_parsing.rb +448 -0
  68. data/lib/musicality/notation/parsing/pitch_parsing.treetop +52 -0
  69. data/lib/musicality/notation/parsing/segment_parsing.rb +141 -0
  70. data/lib/musicality/notation/parsing/segment_parsing.treetop +23 -0
  71. data/lib/musicality/notation/util/interpolation.rb +16 -0
  72. data/lib/musicality/notation/util/piecewise_function.rb +122 -0
  73. data/lib/musicality/notation/util/value_computer.rb +170 -0
  74. data/lib/musicality/performance/conversion/glissando_converter.rb +34 -0
  75. data/lib/musicality/performance/conversion/note_sequence_extractor.rb +98 -0
  76. data/lib/musicality/performance/conversion/portamento_converter.rb +24 -0
  77. data/lib/musicality/performance/conversion/score_collator.rb +126 -0
  78. data/lib/musicality/performance/midi/midi_events.rb +34 -0
  79. data/lib/musicality/performance/midi/midi_util.rb +31 -0
  80. data/lib/musicality/performance/midi/part_sequencer.rb +123 -0
  81. data/lib/musicality/performance/midi/score_sequencer.rb +45 -0
  82. data/lib/musicality/performance/model/note_attacks.rb +19 -0
  83. data/lib/musicality/performance/model/note_sequence.rb +111 -0
  84. data/lib/musicality/performance/util/note_linker.rb +28 -0
  85. data/lib/musicality/performance/util/optimization.rb +31 -0
  86. data/lib/musicality/validatable.rb +38 -0
  87. data/lib/musicality/version.rb +3 -0
  88. data/lib/musicality.rb +81 -0
  89. data/musicality.gemspec +30 -0
  90. data/spec/musicality_spec.rb +7 -0
  91. data/spec/notation/conversion/change_conversion_spec.rb +40 -0
  92. data/spec/notation/conversion/measure_note_map_spec.rb +73 -0
  93. data/spec/notation/conversion/measured_score_conversion_spec.rb +141 -0
  94. data/spec/notation/conversion/measured_score_converter_spec.rb +329 -0
  95. data/spec/notation/conversion/note_time_converter_spec.rb +81 -0
  96. data/spec/notation/conversion/tempo_conversion_spec.rb +40 -0
  97. data/spec/notation/conversion/unmeasured_score_conversion_spec.rb +71 -0
  98. data/spec/notation/conversion/unmeasured_score_converter_spec.rb +116 -0
  99. data/spec/notation/model/change_spec.rb +90 -0
  100. data/spec/notation/model/link_spec.rb +83 -0
  101. data/spec/notation/model/meter_spec.rb +97 -0
  102. data/spec/notation/model/note_spec.rb +183 -0
  103. data/spec/notation/model/part_spec.rb +69 -0
  104. data/spec/notation/model/pitch_spec.rb +180 -0
  105. data/spec/notation/model/program_spec.rb +50 -0
  106. data/spec/notation/model/score_spec.rb +211 -0
  107. data/spec/notation/packing/change_packing_spec.rb +153 -0
  108. data/spec/notation/packing/part_packing_spec.rb +66 -0
  109. data/spec/notation/packing/program_packing_spec.rb +33 -0
  110. data/spec/notation/packing/score_packing_spec.rb +301 -0
  111. data/spec/notation/parsing/articulation_parsing_spec.rb +23 -0
  112. data/spec/notation/parsing/convenience_methods_spec.rb +99 -0
  113. data/spec/notation/parsing/duration_nodes_spec.rb +83 -0
  114. data/spec/notation/parsing/duration_parsing_spec.rb +70 -0
  115. data/spec/notation/parsing/link_nodes_spec.rb +30 -0
  116. data/spec/notation/parsing/link_parsing_spec.rb +13 -0
  117. data/spec/notation/parsing/meter_parsing_spec.rb +23 -0
  118. data/spec/notation/parsing/note_node_spec.rb +87 -0
  119. data/spec/notation/parsing/note_parsing_spec.rb +46 -0
  120. data/spec/notation/parsing/numbers/nonnegative_float_spec.rb +28 -0
  121. data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +11 -0
  122. data/spec/notation/parsing/numbers/nonnegative_rational_spec.rb +11 -0
  123. data/spec/notation/parsing/numbers/positive_float_spec.rb +28 -0
  124. data/spec/notation/parsing/numbers/positive_integer_spec.rb +28 -0
  125. data/spec/notation/parsing/numbers/positive_rational_spec.rb +28 -0
  126. data/spec/notation/parsing/pitch_node_spec.rb +38 -0
  127. data/spec/notation/parsing/pitch_parsing_spec.rb +14 -0
  128. data/spec/notation/parsing/segment_parsing_spec.rb +27 -0
  129. data/spec/notation/util/value_computer_spec.rb +146 -0
  130. data/spec/performance/conversion/glissando_converter_spec.rb +93 -0
  131. data/spec/performance/conversion/note_sequence_extractor_spec.rb +230 -0
  132. data/spec/performance/conversion/portamento_converter_spec.rb +91 -0
  133. data/spec/performance/conversion/score_collator_spec.rb +183 -0
  134. data/spec/performance/midi/midi_util_spec.rb +110 -0
  135. data/spec/performance/midi/part_sequencer_spec.rb +40 -0
  136. data/spec/performance/midi/score_sequencer_spec.rb +50 -0
  137. data/spec/performance/model/note_sequence_spec.rb +147 -0
  138. data/spec/performance/util/note_linker_spec.rb +68 -0
  139. data/spec/performance/util/optimization_spec.rb +73 -0
  140. data/spec/spec_helper.rb +43 -0
  141. metadata +323 -0
@@ -0,0 +1,289 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Musicality
5
+ module Parsing
6
+
7
+ module NonnegativeFloat
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :nonnegative_float
12
+ end
13
+
14
+ module NonnegativeFloat0
15
+ def to_f
16
+ text_value.to_f
17
+ end
18
+
19
+ alias :to_num :to_f
20
+ end
21
+
22
+ def _nt_nonnegative_float
23
+ start_index = index
24
+ if node_cache[:nonnegative_float].has_key?(index)
25
+ cached = node_cache[:nonnegative_float][index]
26
+ if cached
27
+ node_cache[:nonnegative_float][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
28
+ @index = cached.interval.end
29
+ end
30
+ return cached
31
+ end
32
+
33
+ i0 = index
34
+ r1 = _nt_float1
35
+ if r1
36
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
37
+ r0 = r1
38
+ r0.extend(NonnegativeFloat0)
39
+ else
40
+ r2 = _nt_float2
41
+ if r2
42
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
43
+ r0 = r2
44
+ r0.extend(NonnegativeFloat0)
45
+ else
46
+ @index = i0
47
+ r0 = nil
48
+ end
49
+ end
50
+
51
+ node_cache[:nonnegative_float][start_index] = r0
52
+
53
+ r0
54
+ end
55
+
56
+ module Float10
57
+ def exponent
58
+ elements[1]
59
+ end
60
+ end
61
+
62
+ def _nt_float1
63
+ start_index = index
64
+ if node_cache[:float1].has_key?(index)
65
+ cached = node_cache[:float1][index]
66
+ if cached
67
+ node_cache[:float1][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
68
+ @index = cached.interval.end
69
+ end
70
+ return cached
71
+ end
72
+
73
+ i0, s0 = index, []
74
+ s1, i1 = [], index
75
+ loop do
76
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
77
+ r2 = true
78
+ @index += 1
79
+ else
80
+ terminal_parse_failure('[0-9]')
81
+ r2 = nil
82
+ end
83
+ if r2
84
+ s1 << r2
85
+ else
86
+ break
87
+ end
88
+ end
89
+ if s1.empty?
90
+ @index = i1
91
+ r1 = nil
92
+ else
93
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
94
+ end
95
+ s0 << r1
96
+ if r1
97
+ r3 = _nt_exponent
98
+ s0 << r3
99
+ end
100
+ if s0.last
101
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
102
+ r0.extend(Float10)
103
+ else
104
+ @index = i0
105
+ r0 = nil
106
+ end
107
+
108
+ node_cache[:float1][start_index] = r0
109
+
110
+ r0
111
+ end
112
+
113
+ module Float20
114
+ end
115
+
116
+ def _nt_float2
117
+ start_index = index
118
+ if node_cache[:float2].has_key?(index)
119
+ cached = node_cache[:float2][index]
120
+ if cached
121
+ node_cache[:float2][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
122
+ @index = cached.interval.end
123
+ end
124
+ return cached
125
+ end
126
+
127
+ i0, s0 = index, []
128
+ s1, i1 = [], index
129
+ loop do
130
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
131
+ r2 = true
132
+ @index += 1
133
+ else
134
+ terminal_parse_failure('[0-9]')
135
+ r2 = nil
136
+ end
137
+ if r2
138
+ s1 << r2
139
+ else
140
+ break
141
+ end
142
+ end
143
+ if s1.empty?
144
+ @index = i1
145
+ r1 = nil
146
+ else
147
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
148
+ end
149
+ s0 << r1
150
+ if r1
151
+ if has_terminal?(@regexps[gr = '\A[.]'] ||= Regexp.new(gr), :regexp, index)
152
+ r3 = true
153
+ @index += 1
154
+ else
155
+ terminal_parse_failure('[.]')
156
+ r3 = nil
157
+ end
158
+ s0 << r3
159
+ if r3
160
+ s4, i4 = [], index
161
+ loop do
162
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
163
+ r5 = true
164
+ @index += 1
165
+ else
166
+ terminal_parse_failure('[0-9]')
167
+ r5 = nil
168
+ end
169
+ if r5
170
+ s4 << r5
171
+ else
172
+ break
173
+ end
174
+ end
175
+ if s4.empty?
176
+ @index = i4
177
+ r4 = nil
178
+ else
179
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
180
+ end
181
+ s0 << r4
182
+ if r4
183
+ r7 = _nt_exponent
184
+ if r7
185
+ r6 = r7
186
+ else
187
+ r6 = instantiate_node(SyntaxNode,input, index...index)
188
+ end
189
+ s0 << r6
190
+ end
191
+ end
192
+ end
193
+ if s0.last
194
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
195
+ r0.extend(Float20)
196
+ else
197
+ @index = i0
198
+ r0 = nil
199
+ end
200
+
201
+ node_cache[:float2][start_index] = r0
202
+
203
+ r0
204
+ end
205
+
206
+ module Exponent0
207
+ end
208
+
209
+ def _nt_exponent
210
+ start_index = index
211
+ if node_cache[:exponent].has_key?(index)
212
+ cached = node_cache[:exponent][index]
213
+ if cached
214
+ node_cache[:exponent][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
215
+ @index = cached.interval.end
216
+ end
217
+ return cached
218
+ end
219
+
220
+ i0, s0 = index, []
221
+ if (match_len = has_terminal?("e", false, index))
222
+ r1 = true
223
+ @index += match_len
224
+ else
225
+ terminal_parse_failure("e")
226
+ r1 = nil
227
+ end
228
+ s0 << r1
229
+ if r1
230
+ if has_terminal?(@regexps[gr = '\A[+-]'] ||= Regexp.new(gr), :regexp, index)
231
+ r3 = true
232
+ @index += 1
233
+ else
234
+ terminal_parse_failure('[+-]')
235
+ r3 = nil
236
+ end
237
+ if r3
238
+ r2 = r3
239
+ else
240
+ r2 = instantiate_node(SyntaxNode,input, index...index)
241
+ end
242
+ s0 << r2
243
+ if r2
244
+ s4, i4 = [], index
245
+ loop do
246
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
247
+ r5 = true
248
+ @index += 1
249
+ else
250
+ terminal_parse_failure('[0-9]')
251
+ r5 = nil
252
+ end
253
+ if r5
254
+ s4 << r5
255
+ else
256
+ break
257
+ end
258
+ end
259
+ if s4.empty?
260
+ @index = i4
261
+ r4 = nil
262
+ else
263
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
264
+ end
265
+ s0 << r4
266
+ end
267
+ end
268
+ if s0.last
269
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
270
+ r0.extend(Exponent0)
271
+ else
272
+ @index = i0
273
+ r0 = nil
274
+ end
275
+
276
+ node_cache[:exponent][start_index] = r0
277
+
278
+ r0
279
+ end
280
+
281
+ end
282
+
283
+ class NonnegativeFloatParser < Treetop::Runtime::CompiledParser
284
+ include NonnegativeFloat
285
+ end
286
+
287
+
288
+ end
289
+ end
@@ -0,0 +1,29 @@
1
+ module Musicality
2
+ module Parsing
3
+
4
+ grammar NonnegativeFloat
5
+ rule nonnegative_float
6
+ (float1 / float2) {
7
+ def to_f
8
+ text_value.to_f
9
+ end
10
+
11
+ alias :to_num :to_f
12
+ }
13
+ end
14
+
15
+ rule float1
16
+ [0-9]+ exponent
17
+ end
18
+
19
+ rule float2
20
+ [0-9]+ [.] [0-9]+ exponent?
21
+ end
22
+
23
+ rule exponent
24
+ "e" [+-]? [0-9]+
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,64 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Musicality
5
+ module Parsing
6
+
7
+ module NonnegativeInteger
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :nonnegative_integer
12
+ end
13
+
14
+ module NonnegativeInteger0
15
+ def to_i
16
+ text_value.to_i
17
+ end
18
+
19
+ alias :to_num :to_i
20
+ end
21
+
22
+ def _nt_nonnegative_integer
23
+ start_index = index
24
+ if node_cache[:nonnegative_integer].has_key?(index)
25
+ cached = node_cache[:nonnegative_integer][index]
26
+ if cached
27
+ node_cache[:nonnegative_integer][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
28
+ @index = cached.interval.end
29
+ end
30
+ return cached
31
+ end
32
+
33
+ s0, i0 = [], index
34
+ loop do
35
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
36
+ r1 = true
37
+ @index += 1
38
+ else
39
+ terminal_parse_failure('[0-9]')
40
+ r1 = nil
41
+ end
42
+ if r1
43
+ s0 << r1
44
+ else
45
+ break
46
+ end
47
+ end
48
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
49
+ r0.extend(NonnegativeInteger0)
50
+
51
+ node_cache[:nonnegative_integer][start_index] = r0
52
+
53
+ r0
54
+ end
55
+
56
+ end
57
+
58
+ class NonnegativeIntegerParser < Treetop::Runtime::CompiledParser
59
+ include NonnegativeInteger
60
+ end
61
+
62
+
63
+ end
64
+ end
@@ -0,0 +1,17 @@
1
+ module Musicality
2
+ module Parsing
3
+
4
+ grammar NonnegativeInteger
5
+ rule nonnegative_integer
6
+ [0-9]* {
7
+ def to_i
8
+ text_value.to_i
9
+ end
10
+
11
+ alias :to_num :to_i
12
+ }
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,86 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Musicality
5
+ module Parsing
6
+
7
+ module NonnegativeRational
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :nonnegative_rational
12
+ end
13
+
14
+ include NonnegativeInteger
15
+
16
+ include PositiveInteger
17
+
18
+ module NonnegativeRational0
19
+ def nonnegative_integer
20
+ elements[0]
21
+ end
22
+
23
+ def positive_integer
24
+ elements[2]
25
+ end
26
+ end
27
+
28
+ module NonnegativeRational1
29
+ def to_r
30
+ text_value.to_r
31
+ end
32
+
33
+ alias :to_num :to_r
34
+ end
35
+
36
+ def _nt_nonnegative_rational
37
+ start_index = index
38
+ if node_cache[:nonnegative_rational].has_key?(index)
39
+ cached = node_cache[:nonnegative_rational][index]
40
+ if cached
41
+ node_cache[:nonnegative_rational][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
42
+ @index = cached.interval.end
43
+ end
44
+ return cached
45
+ end
46
+
47
+ i0, s0 = index, []
48
+ r1 = _nt_nonnegative_integer
49
+ s0 << r1
50
+ if r1
51
+ if (match_len = has_terminal?("/", false, index))
52
+ r2 = true
53
+ @index += match_len
54
+ else
55
+ terminal_parse_failure("/")
56
+ r2 = nil
57
+ end
58
+ s0 << r2
59
+ if r2
60
+ r3 = _nt_positive_integer
61
+ s0 << r3
62
+ end
63
+ end
64
+ if s0.last
65
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
66
+ r0.extend(NonnegativeRational0)
67
+ r0.extend(NonnegativeRational1)
68
+ else
69
+ @index = i0
70
+ r0 = nil
71
+ end
72
+
73
+ node_cache[:nonnegative_rational][start_index] = r0
74
+
75
+ r0
76
+ end
77
+
78
+ end
79
+
80
+ class NonnegativeRationalParser < Treetop::Runtime::CompiledParser
81
+ include NonnegativeRational
82
+ end
83
+
84
+
85
+ end
86
+ end
@@ -0,0 +1,20 @@
1
+ module Musicality
2
+ module Parsing
3
+
4
+ grammar NonnegativeRational
5
+ include NonnegativeInteger
6
+ include PositiveInteger
7
+
8
+ rule nonnegative_rational
9
+ nonnegative_integer "/" positive_integer {
10
+ def to_r
11
+ text_value.to_r
12
+ end
13
+
14
+ alias :to_num :to_r
15
+ }
16
+ end
17
+ end
18
+
19
+ end
20
+ end