File Coverage

blib/lib/ChordPro/Songbook.pm
Criterion Covered Total %
statement 57 81 70.3
branch 11 20 55.0
condition 13 32 40.6
subroutine 12 14 85.7
pod 0 4 0.0
total 93 151 61.5


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package main;
4              
5             our $options;
6             our $config;
7              
8             package ChordPro::Songbook;
9              
10 79     79   599 use strict;
  79         234  
  79         2482  
11 79     79   436 use warnings;
  79         177  
  79         1988  
12              
13 79     79   435 use ChordPro;
  79         193  
  79         1747  
14 79     79   448 use ChordPro::Config;
  79         162  
  79         1798  
15 79     79   49376 use ChordPro::Song;
  79         406  
  79         3777  
16              
17 79     79   704 use Carp;
  79         220  
  79         5288  
18 79     79   618 use List::Util qw(any);
  79         190  
  79         4476  
19 79     79   588 use File::LoadLines;
  79         213  
  79         68140  
20              
21             sub new {
22 160     160 0 125392 my ($pkg) = @_;
23 160         2234 bless { songs => [ ] }, $pkg;
24             }
25              
26             sub parse_file {
27 141     141 0 20693 my ( $self, $filename, $opts ) = @_;
28 141   100     976 $opts //= {};
29 141   50     342 my $meta = { %{$config->{meta}}, %{delete $opts->{meta}//{}} };
  141         919  
  141         1018  
30 141   50     445 my $defs = { %{delete $opts->{defs}//{}} };
  141         886  
31              
32             # Check for PDF embedding.
33 141 50       1098 if ( $filename =~ /\.pdf$/i ) {
34 0         0 return $self->embed_file( $filename, $meta, $defs );
35             }
36              
37             # Loadlines sets $opts->{_filesource}.
38 141         937 my $lines = loadlines( $filename, $opts );
39             # Sense crd input and convert if necessary.
40 141 50 33     44204 if ( !(defined($options->{a2crd}) && !$options->{a2crd}) and
      66        
      33        
      66        
41             !$options->{fragment}
42 140     140   1912 and any { /\S/ } @$lines # non-blank lines
43 145     145   1218 and $options->{crd} || !any { /^{\s*\w+/ } @$lines ) {
44             warn("Converting $filename to ChordPro format\n")
45 0 0 0     0 if $options->{verbose} || !($options->{a2crd}||$options->{crd});
      0        
46 0         0 require ChordPro::A2Crd;
47 0         0 $lines = ChordPro::A2Crd::a2crd( { lines => $lines } );
48             }
49              
50 141   50     867 $opts //= {};
51              
52             # Used by tests.
53 141         542 for ( "transpose", "transcode" ) {
54 282 100       1001 next unless exists $opts->{$_};
55 9         44 $config->{settings}->{$_} = $opts->{$_};
56             }
57 141         477 for ( "no-substitute", "no-transpose" ) {
58 282 100       880 next unless exists $opts->{$_};
59 1         4 $options->{$_} = $opts->{$_};
60             }
61 141 100       788 bless $config => ChordPro::Config:: if ref $config eq 'HASH';
62              
63 141         317 my $linecnt = 0;
64 141         309 my $songs = 0;
65 141         543 while ( @$lines ) {
66             my $song = ChordPro::Song
67             ->new( $opts->{_filesource} )
68 169         1421 ->parse_song( $lines, \$linecnt, {%$meta}, {%$defs} );
69 169         458 $song->{meta}->{songindex} = 1 + @{ $self->{songs} };
  169         1089  
70 169         366 push( @{ $self->{songs} }, $song );
  169         536  
71 169 100       922 $songs++ if $song->{body};
72             }
73              
74 141 50 66     601 warn("Warning: No songs found in ", $opts->{_filesource}, "\n")
75             unless $songs || $::running_under_test;
76              
77 141         926 return 1;
78             }
79              
80             sub embed_file {
81 0     0 0   my ( $self, $filename, $meta, $defs ) = @_;
82              
83 0 0         unless ( -s -r $filename ) {
84 0           warn("$filename: $! (skipped)\n");
85 0           return;
86             }
87 0           my $type = "pdf";
88              
89 0           my $song = ChordPro::Song->new( $filename );
90 0           $song->{meta}->{songindex} = 1 + @{ $self->{songs} };
  0            
91             $song->{source} =
92 0           { file => $filename,
93             line => 1,
94             embedding => $type,
95             };
96 0   0       my $title = $defs->{title} // $filename;
97 0           $song->{title} = $title;
98 0           $song->{meta}->{title} = [ $title ];
99 0           push( @{ $self->{songs} }, $song );
  0            
100 0 0         $song->dump(0) if $config->{debug}->{song};
101 0           return 1;
102             }
103              
104             # Used by HTML backend.
105             sub structurize {
106 0     0 0   my ( $self ) = @_;
107              
108 0           foreach my $song ( @{ $self->{songs} } ) {
  0            
109 0           $song->structurize;
110             }
111             }
112              
113             1;