Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow [ABC] chords to have durations and "is tied" flags. This goes a…

…gainst the "draft 2.0" ABC grammar we've been working from, but matches the text of the "official" ABC 2.0 standard -- not to mention the Anthony Francis project ABC files.
  • Loading branch information...
commit 83d7ac72c5c94209f6571a349c43ed1dc7284b99 1 parent 5dca9b7
Solomon Foster authored
2  lib/ABC/Actions.pm
View
@@ -46,7 +46,7 @@ class ABC::Actions {
if @( $<mnote> ) == 1 {
make $<mnote>[0].ast;
} else {
- make ABC::Stem.new(@( $<mnote> )>>.ast);
+ make ABC::Stem.new(@( $<mnote> )>>.ast, $<note_length>.ast, ?$<tie>);
}
}
2  lib/ABC/Grammar.pm
View
@@ -18,7 +18,7 @@ grammar ABC::Grammar
regex note_length_denominator { '/' <bottom=number>? }
regex note_length { <top=number>? <note_length_denominator>? }
regex mnote { <pitch> <note_length> <tie>? }
- regex stem { <mnote> | [ '[' <mnote>+ ']' ] }
+ regex stem { <mnote> | [ '[' <mnote>+ ']' <note_length> <tie>? ] }
regex rest_type { <[x..z]> }
regex rest { <rest_type> <note_length> }
5 lib/ABC/Stem.pm
View
@@ -4,9 +4,10 @@ use ABC::Duration;
class ABC::Stem does ABC::Duration {
has @.notes;
+ has $.is-tie;
- method new(@notes) {
+ method new(@notes, ABC::Duration $duration, $is-tie) {
die "Stem must have at least one note" if +@notes == 0;
- self.bless(*, :@notes, :ticks(@notes>>.ticks.max));
+ self.bless(*, :@notes, :ticks(@notes>>.ticks.max * $duration.ticks), :$is-tie);
}
}
26 t/01-regexes.t
View
@@ -200,6 +200,32 @@ use ABC::Grammar;
is $match<stem>[2], "c", 'third note is c';
}
+{
+ my $match = ABC::Grammar.parse("[a2bc]3", :rule<stem>);
+ isa_ok $match, Match, 'Got a match';
+ ok $match, '"[a2bc]3" is a stem';
+ is ~$match, "[a2bc]3", '"[a2bc]3" was the portion matched';
+ is +@( $match<mnote> ), 3, 'Three notes matched';
+ is $match<mnote>[0], "a2", 'first note is a2';
+ is $match<mnote>[1], "b", 'second note is b';
+ is $match<mnote>[2], "c", 'third note is c';
+ is $match<note_length>, "3", 'correct duration';
+ nok ?$match<tie>, 'not tied';
+}
+
+{
+ my $match = ABC::Grammar.parse("[a2bc]3-", :rule<stem>);
+ isa_ok $match, Match, 'Got a match';
+ ok $match, '"[a2bc]3-" is a stem';
+ is ~$match, "[a2bc]3-", '"[a2bc]3-" was the portion matched';
+ is +@( $match<mnote> ), 3, 'Three notes matched';
+ is $match<mnote>[0], "a2", 'first note is a2';
+ is $match<mnote>[1], "b", 'second note is b';
+ is $match<mnote>[2], "c", 'third note is c';
+ is $match<note_length>, "3", 'correct duration';
+ ok ?$match<tie>, 'tied';
+}
+
# (3 is the only case that works currently. :(
# {
# my $match = ABC::Grammar.parse("(2abcd", :rule<tuple>);
22 t/05-actions.t
View
@@ -90,6 +90,28 @@ use ABC::Chord;
}
{
+ my $match = ABC::Grammar.parse("[a2bc]3", :rule<stem>, :actions(ABC::Actions.new));
+ ok $match, 'element recognized';
+ isa_ok $match.ast, ABC::Stem, '$match.ast is an ABC::Stem';
+ is $match.ast.notes[0], "a2", "Pitch 1 a";
+ is $match.ast.notes[1], "b", "Pitch 2 b";
+ is $match.ast.notes[2], "c", "Pitch 3 c";
+ is $match.ast.ticks, 6, "Duration 6 ticks";
+ nok $match.ast.is-tie, "Not tied";
+}
+
+{
+ my $match = ABC::Grammar.parse("[a2bc]/-", :rule<stem>, :actions(ABC::Actions.new));
+ ok $match, 'element recognized';
+ isa_ok $match.ast, ABC::Stem, '$match.ast is an ABC::Stem';
+ is $match.ast.notes[0], "a2", "Pitch 1 a";
+ is $match.ast.notes[1], "b", "Pitch 2 b";
+ is $match.ast.notes[2], "c", "Pitch 3 c";
+ is $match.ast.ticks, 1, "Duration 1 tick";
+ ok $match.ast.is-tie, "Tied";
+}
+
+{
my $match = ABC::Grammar.parse("z/", :rule<rest>, :actions(ABC::Actions.new));
ok $match, 'rest recognized';
isa_ok $match.ast, ABC::Rest, '$match.ast is an ABC::Rest';
Please sign in to comment.
Something went wrong with that request. Please try again.