| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Music::Harmonica::TabsCreator::TabParser; |
|
2
|
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
200212
|
use 5.036; |
|
|
4
|
|
|
|
|
41
|
|
|
4
|
4
|
|
|
4
|
|
21
|
use strict; |
|
|
4
|
|
|
|
|
15
|
|
|
|
4
|
|
|
|
|
105
|
|
|
5
|
4
|
|
|
4
|
|
16
|
use warnings; |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
192
|
|
|
6
|
4
|
|
|
4
|
|
21
|
use utf8; |
|
|
4
|
|
|
|
|
22
|
|
|
|
4
|
|
|
|
|
27
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
4
|
|
|
4
|
|
739
|
use Readonly; |
|
|
4
|
|
|
|
|
5919
|
|
|
|
4
|
|
|
|
|
2027
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.05'; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# This class converts a tab into tones (degrees) relative to the key of C4. |
|
13
|
|
|
|
|
|
|
# It accepts an input specifying the tuning of an harmonica. |
|
14
|
|
|
|
|
|
|
|
|
15
|
2
|
|
|
2
|
0
|
148960
|
sub new ($class, $tab_to_tones) { |
|
|
2
|
|
|
|
|
6
|
|
|
|
2
|
|
|
|
|
7
|
|
|
|
2
|
|
|
|
|
9
|
|
|
16
|
|
|
|
|
|
|
# We order the keys by length, so that we match the longest ones first. |
|
17
|
2
|
|
|
|
|
7
|
my $re = join('|', map { quotemeta } sort { length $b <=> length $a } keys %{$tab_to_tones}); |
|
|
24
|
|
|
|
|
112
|
|
|
|
59
|
|
|
|
|
111
|
|
|
|
2
|
|
|
|
|
20
|
|
|
18
|
2
|
|
|
|
|
169
|
my $self = bless { |
|
19
|
|
|
|
|
|
|
tab_to_tones => $tab_to_tones, |
|
20
|
|
|
|
|
|
|
tab_re => qr/$re/, |
|
21
|
|
|
|
|
|
|
}, $class; |
|
22
|
2
|
|
|
|
|
14
|
return $self; |
|
23
|
|
|
|
|
|
|
} |
|
24
|
|
|
|
|
|
|
|
|
25
|
2
|
|
|
2
|
0
|
16
|
sub parse ($self, $tab) { |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
6
|
|
|
|
2
|
|
|
|
|
5
|
|
|
26
|
2
|
|
|
|
|
4
|
my @out; |
|
27
|
2
|
|
|
|
|
12
|
pos($tab) = 0; |
|
28
|
2
|
|
|
|
|
14
|
while (pos($tab) < length($tab)) { |
|
29
|
16
|
100
|
|
|
|
57
|
next if $tab =~ m/\G\h+/gc; |
|
30
|
|
|
|
|
|
|
|
|
31
|
9
|
50
|
|
|
|
27
|
if ($tab =~ m/\G(\v+)/gc) { |
|
32
|
0
|
|
|
|
|
0
|
push @out, $1; |
|
33
|
0
|
|
|
|
|
0
|
next; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
9
|
50
|
|
|
|
28
|
if ($tab =~ m/ \G \# \s* ( .*? (?:\r\n|\n|\r|\v|\z) )/xgc) { |
|
37
|
0
|
|
|
|
|
0
|
push @out, $1; |
|
38
|
0
|
|
|
|
|
0
|
next; |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
9
|
50
|
|
|
|
170
|
if ($tab =~ m/\G($self->{tab_re})/gc) { |
|
42
|
9
|
|
|
|
|
32
|
push @out, $self->{tab_to_tones}{$1}; |
|
43
|
9
|
|
|
|
|
30
|
next; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
|
|
46
|
0
|
|
|
|
|
0
|
my $pos = pos($tab); |
|
47
|
0
|
|
|
|
|
0
|
substr $tab, $pos, 0, '-->'; |
|
48
|
0
|
|
|
|
|
0
|
$pos++; |
|
49
|
0
|
|
|
|
|
0
|
die "Invalid syntax in the input tab at character ${pos}: ${tab}\n"; |
|
50
|
|
|
|
|
|
|
} |
|
51
|
2
|
50
|
|
|
|
47
|
return wantarray ? @out : \@out; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
1; |