File Coverage

blib/lib/Music/Harmonica/TabsCreator/TabParser.pm
Criterion Covered Total %
statement 38 46 82.6
branch 6 10 60.0
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 51 65 78.4


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;