Music Chords Diagrams: Fixes/improves triggering (#4085)

* Fixes regex to correctly find values

* Adding multiple naming to instruments

* Fixes #3386

* Adds more sharp/flat aliases for ukulele

* Remove debug print

* Multiple whitespace matching

* Adding support for tabs, chords

* Adding tests
master
Nalin Bhardwaj 2017-08-16 04:10:48 +05:30 committed by Rob Emery
parent 9cf4ce5c7e
commit c11be84d6a
3 changed files with 52 additions and 22 deletions

View File

@ -10,7 +10,7 @@ use List::Util qw(min);
zci answer_type => "chord_diagrams";
zci is_cached => 1;
triggers any => "chord", "tab";
triggers any => "chord", "tab", "chords", "tabs";
# Store the instruments that the program will respond to, with a
# list storing the note of each string in order. (Add one to note
@ -18,11 +18,13 @@ triggers any => "chord", "tab";
my %instruments = (
guitar => {
chords => decode_json(share('guitar.json')->slurp),
strings => 6
strings => 6,
names => 'guitar'
},
ukulele => {
chords => decode_json(share('ukulele.json')->slurp),
strings => 4
strings => 4,
names => 'ukulele|uke'
}
);
@ -142,7 +144,7 @@ sub gen_svg {
# used in items
my %mod_hash = (sharp => 1, b => -1);
my %mod_hash = (sharp => '#', b => 'b');
# The input parser. Uses regex to find the key to put the chord in, and the
# chord if they are conjoined.
@ -151,12 +153,12 @@ my %mod_hash = (sharp => 1, b => -1);
sub items {
my @words = split(" ", lc $_[0]);
$_[0] = join("sharp", split("#", $_[0]));
my ($temp, $key, $mod, $chord, $dom, $temp2) = /( |^)([a-g])(sharp|b|)(m|min|minor|M|maj|major|sus[24]|aug9?|)(5|7|9|11|13|)( |$)/i ;
my ($temp, $key, $mod, $chord, $dom, $temp2) = /( |^)(?:\s)*([a-g])(?:\s)*(sharp|b|)(?:\s)*(m|min|minor|M|maj|major|sus[24]|aug9?|)(?:\s)*(5|7|9|11|13|)(?:\s)*( |$)/i;
if(/( |^)(5|7|9)( |$)/i) { ($temp, $dom, $temp2) = /( |^)(5|7|9|11|13)( |$)/i; }
if(/( |^)(5|7|9)th( |$)/i) { ($temp, $dom, $temp2) = /( |^)(5|7|9|11|13)th( |$)/i; }
$mod = $mod ? ($mod_hash{$mod} || 0) : 0;
$mod = $mod ? ($mod_hash{$mod} || '') : '';
$key ||= "";
$dom ||= "";
$chord ||= "";
@ -171,11 +173,12 @@ sub items {
my $instr;
foreach my $i (keys %instruments) {
if(grep(/^$i$/, @words)) {
if(grep(/^$instruments{$i}{"names"}$/, @words)) {
$instr = $i;
last;
}
}
return $instr, $chord, uc $key, $mod, $dom;
};
@ -198,22 +201,13 @@ sub get_chord {
return;
};
# turn a mod number into a symbol
sub mod_sign {
return "b" if $_ eq -1;
return "#" if $_ eq 1;
return "";
};
# Handle statement
handle remainder => sub {
my ($instr_name, $chord_name, $key_name, $mod, $dom) = items($_);
return unless $instr_name && $chord_name && $key_name;
my $strings = $instruments{$instr_name}{"strings"};
my $length = 4;
$mod = mod_sign $mod;
my $input = join(" ", (uc $key_name) . $mod, $chord_name . $dom, "guitar chord");
return unless my $r = get_chord($key_name . $mod, $chord_name . $dom, $instruments{$instr_name}{"chords"});
my @results = @{$r};

View File

@ -238,7 +238,7 @@
[ 0, 0, 1, 3 ]
]
}]}, {
"root": ["C#"],
"root": ["C#", "Db"],
"types": [{
"name": "maj",
"variations": [
@ -345,7 +345,7 @@
[ 2, 2, 3, 0 ]
]
}]}, {
"root": ["D#"],
"root": ["D#", "Eb"],
"types": [{
"name": "maj",
"variations": [
@ -507,7 +507,7 @@
[ 3, 0, 1, 3 ]
]
}]}, {
"root": ["F#"],
"root": ["F#", "Gb"],
"types": [{
"name": "maj",
"variations": [
@ -615,7 +615,7 @@
[ 0, 2, 3, 3 ]
]
}]}, {
"root": ["G#"],
"root": ["G#", "Ab"],
"types": [{
"name": "maj",
"variations": [

View File

@ -46,13 +46,49 @@ structured_answer => {
}
},
}),
'Eb uke tabs' => test_zci(
'chord_diagrams',
structured_answer => {
id => 'chord_diagrams',
name => 'Music',
data => re(qr/.*/),
templates => {
group => "base",
detail => 0,
options => {
content => 'DDH.chord_diagrams.detail'
},
variants => {
tile => 'narrow'
}
},
}),
'A major guitar tab' => test_zci(
'chord_diagrams',
structured_answer => {
id => 'chord_diagrams',
name => 'Music',
data => re(qr/.*/),
templates => {
group => "base",
detail => 0,
options => {
content => 'DDH.chord_diagrams.detail'
},
variants => {
tile => 'narrow'
}
},
}),
# check that certain things don't trigger it:
'C# programming' => undef,
'C programming' => undef,
'D programming' => undef,
'guitar chord finder' => undef,
'guitar chord fminute' => undef,
'G' => undef
'G' => undef,
'A sharp tabs' => undef,
'randomstring guitar chords' => undef
);
done_testing;