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   633 use strict;
  79         171  
  79         2474  
11 79     79   426 use warnings;
  79         171  
  79         1907  
12              
13 79     79   427 use ChordPro;
  79         154  
  79         1525  
14 79     79   393 use ChordPro::Config;
  79         167  
  79         1803  
15 79     79   48291 use ChordPro::Song;
  79         310  
  79         3581  
16              
17 79     79   621 use Carp;
  79         213  
  79         6275  
18 79     79   593 use List::Util qw(any);
  79         213  
  79         4417  
19 79     79   606 use File::LoadLines;
  79         218  
  79         66158  
20              
21             sub new {
22 160     160 0 125256 my ($pkg) = @_;
23 160         2252 bless { songs => [ ] }, $pkg;
24             }
25              
26             sub parse_file {
27 141     141 0 21105 my ( $self, $filename, $opts ) = @_;
28 141   100     944 $opts //= {};
29 141   50     318 my $meta = { %{$config->{meta}}, %{delete $opts->{meta}//{}} };
  141         544  
  141         1064  
30 141   50     450 my $defs = { %{delete $opts->{defs}//{}} };
  141         874  
31              
32             # Check for PDF embedding.
33 141 50       1086 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     43404 if ( !(defined($options->{a2crd}) && !$options->{a2crd}) and
      66        
      33        
      66        
41             !$options->{fragment}
42 140     140   2061 and any { /\S/ } @$lines # non-blank lines
43 145     145   1283 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     919 $opts //= {};
51              
52             # Used by tests.
53 141         531 for ( "transpose", "transcode" ) {
54 282 100       1004 next unless exists $opts->{$_};
55 9         46 $config->{settings}->{$_} = $opts->{$_};
56             }
57 141         480 for ( "no-substitute", "no-transpose" ) {
58 282 100       907 next unless exists $opts->{$_};
59 1         4 $options->{$_} = $opts->{$_};
60             }
61 141 100       759 bless $config => ChordPro::Config:: if ref $config eq 'HASH';
62              
63 141         362 my $linecnt = 0;
64 141         303 my $songs = 0;
65 141         621 while ( @$lines ) {
66             my $song = ChordPro::Song
67             ->new( $opts->{_filesource} )
68 169         1417 ->parse_song( $lines, \$linecnt, {%$meta}, {%$defs} );
69 169         475 $song->{meta}->{songindex} = 1 + @{ $self->{songs} };
  169         1348  
70 169         337 push( @{ $self->{songs} }, $song );
  169         529  
71 169 100       952 $songs++ if $song->{body};
72             }
73              
74 141 50 66     608 warn("Warning: No songs found in ", $opts->{_filesource}, "\n")
75             unless $songs || $::running_under_test;
76              
77 141         962 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;