ramekin 0.0.10 → 0.1.1
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/README.md +86 -11
- data/lib/ramekin/cli.rb +4 -0
- data/lib/ramekin/errors.rb +3 -1
- data/lib/ramekin/legato.rb +3 -3
- data/lib/ramekin/loop_allocator.rb +47 -0
- data/lib/ramekin/meta.rb +29 -3
- data/lib/ramekin/note_aggregator.rb +12 -6
- data/lib/ramekin/renderer.rb +7 -5
- data/lib/ramekin/tokenizer.rb +2 -2
- data/lib/ramekin.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 999d9354b8f31a49551d78893fe986a38f9ff8ca4e2ecc880970bdde628e8ac0
|
4
|
+
data.tar.gz: f3e29e81592be14e9b888de2ca731cbc285fb43763b80e2320486bbf17694434
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4d0bba97851f3d9039710c750fbd1f2cdfb65f84d8279b628901b1e7e23990f5e7319264ba4f3dca4058bc7bc5b99b21078c8d65c0a20da06bb50cb6b740539
|
7
|
+
data.tar.gz: b69597095b27d7a1bfb268729bf44c510bdcf4109a747a677f6a5f9665948a71dcaf4a4c696d976c480373b84762b699cb2aad71749dfc21f64997e231ab9d8d
|
data/README.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
<style>
|
2
|
+
img { float: right; }
|
3
|
+
</style>
|
4
|
+
|
5
|
+

|
6
|
+
|
1
7
|
# Ramekin
|
2
8
|
|
3
9
|
Ramekin is a pre-processor for AddMusicK syntax that is in very early development.
|
@@ -53,6 +59,9 @@ ramekin compile -i filename.rmk [flags]
|
|
53
59
|
--play
|
54
60
|
play the generated SPC file. will automatically
|
55
61
|
set up an SPC player if none is detected.
|
62
|
+
--package my-cool-folder/
|
63
|
+
create a package directory suitable for submission
|
64
|
+
to SMWC, complete with README and packaged samples.
|
56
65
|
--wav filename.wav
|
57
66
|
--wav filename.wav:N
|
58
67
|
(non-windows only)
|
@@ -93,6 +102,7 @@ A list of some ramekin preprocessor features (see `spec/rmk` for some examples!)
|
|
93
102
|
|
94
103
|
* The metadata section (before any channels) is fairly different, I recommend reading the metadata part of the guide below.
|
95
104
|
* Macros ("replacements") are implemented in a much more robust way (*with* tokenization), and can no longer interrupt other tokens. The generated txt will not contain any replacements.
|
105
|
+
* Loops can be given arbitrary names using any combination of letters, numbers, underscores, or dashes. `(my-cool-loop)[ ... ]` is valid syntax. These are case sensitive, and are assigned numbers when compiled to AddmusicK syntax.
|
96
106
|
* Adopted the transposition syntax `_+N`, `_-N`, and `_0` from General MML. Compiles to `$fa$02$XX`.
|
97
107
|
* `#adsr:A,D,S,RR` syntax for ADSR. Also usable on an `#instrument` declaration, with the same syntax. A, D, and R are flipped so that higher numbers are longer times.
|
98
108
|
* `v+X` and `v-X` are volumes relative to the last `vXXX` command. Useful for separating expression from mixing.
|
@@ -119,7 +129,7 @@ b8 #bend >>c16^16 ^^4
|
|
119
129
|
|
120
130
|
* In ramekin, there is no difference between instrument `#adsr` syntax and the one in the pattern data. They are both compiled to their respective syntaxes in the txt.
|
121
131
|
|
122
|
-
* Tempo can alternately be declared with `#bpm:128`. This will be converted to the nearest `tXX` command.
|
132
|
+
* Tempo can alternately be declared with `#bpm:128`. This will be converted to the nearest `tXX` command. If the tempo is over `t60` (`#bpm:146`), the tempo and all note and event lengths will be halved automatically. This is similar to `#halvetempo` except that it is done automatically.
|
123
133
|
* `p0,0` compiles to `$df`.
|
124
134
|
* "Legato tie" represented by `~`, which will use `$f4$01` at appropriate times to cause the note transition to be played legato.
|
125
135
|
* If you ever want to see what exactly Ramekin is generating, just use `--txt` and you can inspect the generated AddmusicK syntax manually!
|
@@ -163,9 +173,6 @@ w150
|
|
163
173
|
|
164
174
|
; sets the bpm. (todo: mention the reasonable range for this)
|
165
175
|
#bpm:130
|
166
|
-
|
167
|
-
; echo settings. this syntax is likely to change in the future, because it sucks
|
168
|
-
#echo $ef$ff$df$df $f1$02$cf$01
|
169
176
|
```
|
170
177
|
|
171
178
|
### Instrument definitions
|
@@ -217,16 +224,20 @@ It is generally advised to stick with the default tuning. The `o5` declaration s
|
|
217
224
|
Echo settings can be set up with the `#echo/...` family of directives:
|
218
225
|
|
219
226
|
```elisp
|
227
|
+
; select which channels have echo enabled
|
220
228
|
#echo/channels:0,1,2,3
|
221
229
|
; or
|
222
230
|
#echo/channels:all
|
223
231
|
; or
|
224
232
|
#echo/channels:none
|
225
233
|
|
226
|
-
#echo/volume:20 ; range from -
|
234
|
+
#echo/volume:20 ; range from -80 to 7f, use negatives for surround
|
227
235
|
#echo/volume:20,30 ; set different values for left vs right echo
|
228
|
-
#echo/feedback:48 ; range from -
|
236
|
+
#echo/feedback:48 ; range from -80 to 7f, use negatives for surround
|
229
237
|
#echo/fir:1 ; 1 or 0 to enable/disable the FIR filter
|
238
|
+
|
239
|
+
; later, you can use this to toggle the echo on a channel.
|
240
|
+
#echo/toggle
|
230
241
|
```
|
231
242
|
|
232
243
|
|
@@ -296,7 +307,7 @@ Personally, I tend to use `l16` across the whole track for consistency.
|
|
296
307
|
|
297
308
|
Just as in Addmusick, there are two kinds of loops:
|
298
309
|
|
299
|
-
* Regular loops, marked with `[ ]`, which can optionally be tagged with a
|
310
|
+
* Regular loops, marked with `[ ]`, which can optionally be tagged with a name, as in `(my-cool-loop)[ ]`. These can not only loop immediately but also be called at arbitrary points.
|
300
311
|
* Super loops, marked with `[[ ]]`, which can only loop immediately, but can nest either inside or outside of regular loops.
|
301
312
|
|
302
313
|
This is best shown with an example:
|
@@ -306,11 +317,75 @@ This is best shown with an example:
|
|
306
317
|
[ defg ]4 ; plays defg four times (regular loop)
|
307
318
|
[[ abcd ]]4 ; plays abcd four times (superloop)
|
308
319
|
* ; calls the last defined regular loop, in this case plays defg
|
309
|
-
|
310
|
-
(
|
311
|
-
(
|
320
|
+
*3 ; same thing but 3 times
|
321
|
+
(blungus)[ fedc ] ; defines a loop named (blungus), also plays fedc immediately
|
322
|
+
(blungus) ; calls the loop (blungus)
|
323
|
+
(blungus)2 ; calls the loop (blungus) twice
|
312
324
|
```
|
313
325
|
|
314
326
|
### Expression and effects
|
315
327
|
|
316
|
-
Volume
|
328
|
+
#### Volume Expression
|
329
|
+
|
330
|
+
Volume can be set with `vXXX`, where `XXX` is a number between 0 and 255. This command also sets the current "reference volume", which can be referenced with commands `v+XX` and `v-XX`, where XX is a number to be added or subtracted to the reference volume. This way, you can add dynamics to your drums or melody lines, while also easily being able to change the overall volume of the section.
|
331
|
+
|
332
|
+
#### Pitch Expression
|
333
|
+
|
334
|
+
Pitch expression can be accomplished in two ways:
|
335
|
+
|
336
|
+
* `pA,B,C`, where A,B, and C are numbers, can be used to set vibrato - a slight pitch wiggle that starts sometime after a note is started. `A` specifies the delay - how long to wait before wiggling the pitch, `B` specifies the speed - how fast to wiggle the pitch, and `C` specifies the amplitude - how much to wiggle the pitch. Turn off vibrato with `p0,0`.
|
337
|
+
* Manual pitch bends are fairly straightforward in ramekin, using `#bend` and `^^`:
|
338
|
+
|
339
|
+
```elisp
|
340
|
+
; b plays for an 8th note, then bends up to c for an eighth note,
|
341
|
+
; then continues on c for a quarter note.
|
342
|
+
b8 #bend >c8 ^^ c4
|
343
|
+
```
|
344
|
+
|
345
|
+
#### Panning Expression
|
346
|
+
|
347
|
+
Panning can be specified with the command `yLX` or `yRX`, where X is a number from 1-10. To reset panning to the center, use `yC`:
|
348
|
+
|
349
|
+
```elisp
|
350
|
+
yR10 ; maximum pan right
|
351
|
+
yR2 ; tasteful pan right
|
352
|
+
yC ; pan center
|
353
|
+
yL2 ; tasteful pan left
|
354
|
+
yl10 ; maximum pan left
|
355
|
+
```
|
356
|
+
|
357
|
+
## Hex
|
358
|
+
|
359
|
+
For those who want to use AddmusicK features that are not currently supported by Ramekin, Ramekin still supports manual entry of hex values with `$XX`. While these can be made slightly easier to use with macros, I would very much appreciate it if you could open an issue here or contact me via SMWC or Discord if you find you are using these heavily.
|
360
|
+
|
361
|
+
## Macros
|
362
|
+
|
363
|
+
To make your life easier, Ramekin implements a very similar macro ("replacement") system as AddmusicK - allowing you to define all manner of custom shortcuts for maximum efficiency and tweakability. (Note that Ramekin's implementation of macros is far more robust than AddmusicK's, and will not interrupt other tokens - e.g. a macro called `F` will not be applied to something like `$EF`).
|
364
|
+
|
365
|
+
A macro looks like this:
|
366
|
+
|
367
|
+
```elisp
|
368
|
+
"MY_COOL_MACRO=@smwacousticbass o3 v150"
|
369
|
+
```
|
370
|
+
|
371
|
+
Now whenever you type `MY_COOL_MACRO` in a channel, it will be as if you typed `@smwacousticbass o3 v150`. This can be used to define all sorts of helpers, including some dynamics helpers:
|
372
|
+
|
373
|
+
```elisp
|
374
|
+
"F=v+0" ; forte
|
375
|
+
"M=v-20" ; mezzo
|
376
|
+
"P=v-40" ; piano
|
377
|
+
```
|
378
|
+
|
379
|
+
Or drum instrument helpers:
|
380
|
+
|
381
|
+
```elisp
|
382
|
+
"K=@smwkick o4"
|
383
|
+
"S=@smwsnare o4"
|
384
|
+
"H=@smwshaker o4"
|
385
|
+
```
|
386
|
+
|
387
|
+
Or anything else you might find helpful.
|
388
|
+
|
389
|
+
# Thank you for trying out Ramekin!
|
390
|
+
|
391
|
+
If you find any bugs, please report them in the issue tracker here on Codeberg. If you have questions, design ideas, or complaints, or just want to chat, please feel free to ask anything in [my discord](https://jneen.ca/discord). Cheers!
|
data/lib/ramekin/cli.rb
CHANGED
@@ -44,6 +44,9 @@ module Ramekin
|
|
44
44
|
'(compiles and installs spct - requires git,cmake,make)'
|
45
45
|
end
|
46
46
|
$stderr.puts " #{default_text}"
|
47
|
+
$stderr.puts " --package my-cool-folder/"
|
48
|
+
$stderr.puts " create a package directory suitable for submission"
|
49
|
+
$stderr.puts " to SMWC, complete with README and packaged samples."
|
47
50
|
unless Ramekin.config.windows?
|
48
51
|
$stderr.puts " --wav filename.wav"
|
49
52
|
$stderr.puts " --wav filename.wav:N"
|
@@ -162,6 +165,7 @@ module Ramekin
|
|
162
165
|
outer_chain = Processor.compose(
|
163
166
|
MacroExpander,
|
164
167
|
ScanForL,
|
168
|
+
LoopAllocator,
|
165
169
|
)
|
166
170
|
|
167
171
|
expanded = outer_chain.call(tokens)
|
data/lib/ramekin/errors.rb
CHANGED
@@ -15,7 +15,7 @@ module Ramekin
|
|
15
15
|
def self.error!(e, nesting: 0)
|
16
16
|
all << e
|
17
17
|
|
18
|
-
if ENV['RAMEKIN_DEBUG'] == '1'
|
18
|
+
if ENV['RAMEKIN_DEBUG'] == '1' && ENV['DISABLE_PRY'] != 'true'
|
19
19
|
if nesting >= 0
|
20
20
|
Pry.config.hooks.add_hook(:before_session, :ramekin) do |output, binding, pry|
|
21
21
|
Pry.config.hooks.delete_hook(:before_session, :ramekin)
|
@@ -25,6 +25,8 @@ module Ramekin
|
|
25
25
|
|
26
26
|
binding.pry
|
27
27
|
end
|
28
|
+
|
29
|
+
nil
|
28
30
|
end
|
29
31
|
|
30
32
|
def initialize(start, fin, message)
|
data/lib/ramekin/legato.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Ramekin
|
2
2
|
class LegatoStart < Element
|
3
|
-
def to_amk
|
3
|
+
def to_amk(*)
|
4
4
|
'$f4$01'
|
5
5
|
end
|
6
6
|
|
@@ -32,10 +32,10 @@ module Ramekin
|
|
32
32
|
@note.ticks / 2
|
33
33
|
end
|
34
34
|
|
35
|
-
def to_amk(current_octave=nil)
|
35
|
+
def to_amk(current_octave=nil, divisor=1)
|
36
36
|
post_ticks = @note.ticks - ticks
|
37
37
|
post_len = KNOWN_LENGTHS.fetch(post_ticks) { "=#{post_ticks}" }
|
38
|
-
"#{octave_amk(current_octave)}#{note_name}#{length_amk}$f4$01^#{post_len}"
|
38
|
+
"#{octave_amk(current_octave)}#{note_name}#{length_amk(divisor)}$f4$01^#{post_len}"
|
39
39
|
end
|
40
40
|
|
41
41
|
def inspect
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Ramekin
|
2
|
+
class LoopAllocator < Processor
|
3
|
+
def call(&b)
|
4
|
+
tokens = @stream.to_a
|
5
|
+
|
6
|
+
loop_defs = tokens.select do |tok|
|
7
|
+
Token === tok && tok.type == :loop && tok.value && !tok.value.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
index = 0
|
11
|
+
indices = {}
|
12
|
+
used = Set.new
|
13
|
+
|
14
|
+
numbered, named = loop_defs.partition do |tok|
|
15
|
+
/\A\d+\z/.match?(tok.value)
|
16
|
+
end
|
17
|
+
|
18
|
+
numbered.each do |tok|
|
19
|
+
num = indices[tok.value] = tok.value.to_i
|
20
|
+
tok.meta[:number] = num
|
21
|
+
used << num
|
22
|
+
end
|
23
|
+
|
24
|
+
named.each do |tok|
|
25
|
+
if indices.key?(tok.value)
|
26
|
+
error! "multiple definitions of (#{tok.value})", el: tok
|
27
|
+
next
|
28
|
+
end
|
29
|
+
|
30
|
+
index += 1
|
31
|
+
index += 1 while used.include?(index)
|
32
|
+
indices[tok.value] = index
|
33
|
+
tok.meta[:number] = index
|
34
|
+
end
|
35
|
+
|
36
|
+
tokens.each do |token|
|
37
|
+
if Token === token && token.type == :loop_call
|
38
|
+
token.meta[:number] = indices.fetch(token.value) do
|
39
|
+
error! "no such loop", el: token
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
yield token
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/ramekin/meta.rb
CHANGED
@@ -48,6 +48,34 @@ module Ramekin
|
|
48
48
|
)
|
49
49
|
end
|
50
50
|
|
51
|
+
def t_value
|
52
|
+
t_with_divisor[0]
|
53
|
+
end
|
54
|
+
|
55
|
+
def divisor
|
56
|
+
t_with_divisor[1]
|
57
|
+
end
|
58
|
+
|
59
|
+
def t_with_divisor
|
60
|
+
return [50, 1] if @tempo.nil?
|
61
|
+
|
62
|
+
@t_with_divisor ||= begin
|
63
|
+
t = case @tempo.type
|
64
|
+
when :t then @tempo.value
|
65
|
+
when :bpm then (@tempo.value.to_f * 8192 / 20025.0)
|
66
|
+
end
|
67
|
+
|
68
|
+
t = t.to_f
|
69
|
+
divisor = 1
|
70
|
+
while t > 60
|
71
|
+
t /= 2
|
72
|
+
divisor *= 2
|
73
|
+
end
|
74
|
+
|
75
|
+
[t.round, divisor]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
51
79
|
def parse
|
52
80
|
loop do
|
53
81
|
break if @elements.empty?
|
@@ -58,7 +86,7 @@ module Ramekin
|
|
58
86
|
when :amk then @amk = @current
|
59
87
|
when :option then @options[@current.value] = true
|
60
88
|
when :w then @volume = @current
|
61
|
-
when :t, :bpm then @tempo = @current
|
89
|
+
when :t, :bpm then @tempo = @current; @t_with_divisor = nil
|
62
90
|
else
|
63
91
|
error! 'invalid token in header'
|
64
92
|
end
|
@@ -90,8 +118,6 @@ module Ramekin
|
|
90
118
|
@instruments << Instrument.new(@current_pack, @current_directive, name, path, extensions)
|
91
119
|
when 'default', 'optimized' then @sample_groups << @current
|
92
120
|
|
93
|
-
# TODO: real echo syntax
|
94
|
-
when 'echo' then @echo = expect_args(*([:hex] * 8))
|
95
121
|
when 'echo/channels'
|
96
122
|
channels = @current_directive.values[1]
|
97
123
|
case channels
|
@@ -57,10 +57,16 @@ module Ramekin
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
def length_amk
|
60
|
+
def length_amk(div)
|
61
|
+
if ticks % div != 0
|
62
|
+
divisible = div == 2 ? 'even' : "divisible by #{div}"
|
63
|
+
error!("too fast! tick count must be #{divisible} at this tempo", el: self)
|
64
|
+
end
|
65
|
+
|
66
|
+
t = ticks / div
|
61
67
|
# we use l16
|
62
|
-
return '' if
|
63
|
-
KNOWN_LENGTHS.fetch(
|
68
|
+
return '' if t == 12
|
69
|
+
KNOWN_LENGTHS.fetch(t) { "=#{t}" }
|
64
70
|
end
|
65
71
|
|
66
72
|
def octave_amk(current_octave=nil)
|
@@ -80,8 +86,8 @@ module Ramekin
|
|
80
86
|
end
|
81
87
|
end
|
82
88
|
|
83
|
-
def to_amk(current_octave=nil)
|
84
|
-
return "#{octave_amk(current_octave)}#{note_name}#{length_amk}"
|
89
|
+
def to_amk(current_octave=nil, divisor=1)
|
90
|
+
return "#{octave_amk(current_octave)}#{note_name}#{length_amk(divisor)}"
|
85
91
|
end
|
86
92
|
|
87
93
|
def repr
|
@@ -94,7 +100,7 @@ module Ramekin
|
|
94
100
|
|
95
101
|
def ticks
|
96
102
|
if @extensions.empty? && default_length.nil?
|
97
|
-
|
103
|
+
return 192 / 16
|
98
104
|
end
|
99
105
|
|
100
106
|
exts = @extensions
|
data/lib/ramekin/renderer.rb
CHANGED
@@ -101,7 +101,7 @@ module Ramekin
|
|
101
101
|
yield "}\n\n"
|
102
102
|
end
|
103
103
|
|
104
|
-
yield "t#{
|
104
|
+
yield "t#{m.t_value} ; main tempo (0-60)\n" if m.tempo
|
105
105
|
yield "w#{m.volume.value} ; main volume (0-255)\n" if m.volume
|
106
106
|
yield "l16\n\n"
|
107
107
|
|
@@ -143,12 +143,14 @@ module Ramekin
|
|
143
143
|
if (old_tick-1) / 192 != (@tick-1) / 192
|
144
144
|
yield "\n"
|
145
145
|
end
|
146
|
-
|
146
|
+
divisor = @track.meta.divisor
|
147
|
+
|
148
|
+
yield el.to_amk(@octave, @track.meta.divisor)
|
147
149
|
@octave = el.octave unless el.rest?
|
148
150
|
when MacroDefinition
|
149
151
|
# pass
|
150
152
|
when LegatoStart, LegatoLastNote
|
151
|
-
yield el.to_amk
|
153
|
+
yield el.to_amk(@octave, @track.meta.divisor)
|
152
154
|
when Instrument
|
153
155
|
yield "@#{@instrument_index[el.name.value]}"
|
154
156
|
when Token
|
@@ -241,14 +243,14 @@ module Ramekin
|
|
241
243
|
yield " [[ "
|
242
244
|
when :loop
|
243
245
|
if token.value
|
244
|
-
yield " (#{token.
|
246
|
+
yield " (#{token.meta[:number]})[ "
|
245
247
|
else
|
246
248
|
yield " [ "
|
247
249
|
end
|
248
250
|
when :loop_end
|
249
251
|
yield " ]#{token.value} "
|
250
252
|
when :loop_call
|
251
|
-
yield " (#{token.
|
253
|
+
yield " (#{token.meta[:number]})#{token.values[1]} "
|
252
254
|
when :star
|
253
255
|
yield "*#{token.value}"
|
254
256
|
when :superloop_end
|
data/lib/ramekin/tokenizer.rb
CHANGED
@@ -243,9 +243,9 @@ module Ramekin
|
|
243
243
|
return [:superloop_end, m(1)] if match /\]\](\d*)/
|
244
244
|
|
245
245
|
return [:remote_def, m(1)] if match /[(]!(\d+)[)]\[/
|
246
|
-
return [:loop, m(1)] if match /(?:[(](\
|
246
|
+
return [:loop, m(1)] if match /(?:[(]([\w-]+)[)])?\[/
|
247
247
|
return [:loop_end, m(1)] if match /\](\d*)/
|
248
|
-
return [:loop_call, m(1), m(2)] if match /[(](\
|
248
|
+
return [:loop_call, m(1), m(2)] if match /[(]([\w-]+)[)](\d+)?/
|
249
249
|
|
250
250
|
# this needs a reparse
|
251
251
|
return remote(:remote_call, m(1)) if match /[(]!(\d*)/
|
data/lib/ramekin.rb
CHANGED
@@ -11,6 +11,7 @@ require_relative 'ramekin/processor'
|
|
11
11
|
require_relative 'ramekin/macros'
|
12
12
|
require_relative 'ramekin/note_aggregator'
|
13
13
|
require_relative 'ramekin/legato'
|
14
|
+
require_relative 'ramekin/loop_allocator'
|
14
15
|
require_relative 'ramekin/meta'
|
15
16
|
require_relative 'ramekin/channel_separator'
|
16
17
|
require_relative 'ramekin/volume'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ramekin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jneen
|
8
8
|
autorequire:
|
9
9
|
bindir: gembin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: strscan
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/ramekin/element.rb
|
86
86
|
- lib/ramekin/errors.rb
|
87
87
|
- lib/ramekin/legato.rb
|
88
|
+
- lib/ramekin/loop_allocator.rb
|
88
89
|
- lib/ramekin/macros.rb
|
89
90
|
- lib/ramekin/meta.rb
|
90
91
|
- lib/ramekin/note_aggregator.rb
|