SF’s ABC project continues to be dead in the water, but that hasn’t stopped me from needing some quick ABC scripts. I’m preparing a mini-book of tunes for an Irish Traditional Dance Music workshop, and needed a couple quick programming tricks to make my life easier.
First, a file of ABC tunes should have a unique “X:” index field for each tune. I’d gathered these tunes from around the Internet; correspondingly, about half had “X: 1”, and the rest had some random number. This was easily fixed with a simple Perl 6 script:
my $x = 1; for $*IN.lines { when /^X\:/ { say "X: { $x++ }"; } say $_; }
The only thing at all odd here is that I’ve used when
in a for
loop. It just smartmatches the topic ($_
) against the regex there, and if it’s a match, executes the code that follows and then skips to the next iteration of the loop.
The trickier thing I needed to do was transpose a couple of tunes, because the versions I found on the Internet were in the wrong key. Cutely, this is pretty easily done with the .trans
method in Perl 6.
for $*IN.lines -> $line { # say (~$line).trans("C..GABc..gab" => "FGABc..gab"); # from D to G say (~$line).trans("C..GABc..gab" => "D..GABc..gabh"); # from G to A }
This needs to be applied only to the notes of the tune, and if you use the “G to A” transposition and you have an “h” as a note, you need to switch it to “c'”. (You also need to change the declared key signature in the tune’s header. And accidentals might need work. This is definitely crude ABC-handling code, but it suited my purposes perfectly last night.)
There is one big gotcha here. Why is it (~$line)
instead of just $line
? Well, internally .lines
is calling .chomp
. And apparently .chomp
no longer returns a Rakudo Str
, which seems to mean some other .trans
is executed, causing no end of problems.
Anyway, at some point I intend to try to get the real ABC module working in Rakudo (if no one else beats me to it). In the meantime, I’ve got to survive a weekend’s worth of folk festival first.
Leave a Reply