File Coverage

blib/lib/Data/iRealPro/Output/Text.pm
Criterion Covered Total %
statement 80 89 89.8
branch 18 36 50.0
condition 8 15 53.3
subroutine 12 12 100.0
pod 0 4 0.0
total 118 156 75.6


line stmt bran cond sub pod time code
1             #! perl
2              
3             # Data::iRealPro::Output::Text -- produce editable text
4              
5             # Author : Johan Vromans
6             # Created On : Tue Sep 6 14:58:26 2016
7             # Last Modified By: Johan Vromans
8             # Last Modified On: Tue Nov 6 08:27:04 2018
9             # Update Count : 105
10             # Status : Unknown, Use with caution!
11              
12             ################ Common stuff ################
13              
14 3     3   3389 use strict;
  3         8  
  3         94  
15 3     3   16 use warnings;
  3         6  
  3         84  
16 3     3   15 use Carp;
  3         6  
  3         150  
17 3     3   1153 use utf8;
  3         32  
  3         18  
18              
19             package Data::iRealPro::Output::Text;
20              
21 3     3   152 use parent qw( Data::iRealPro::Output::Base );
  3         6  
  3         24  
22              
23 3     3   164 use Data::iRealPro::URI;
  3         8  
  3         61  
24 3     3   15 use Data::iRealPro::Playlist;
  3         6  
  3         67  
25 3     3   16 use Data::iRealPro::Song;
  3         6  
  3         3339  
26              
27             sub options {
28 2     2 0 6 my $self = shift;
29 2         5 [ @{ $self->SUPER::options }, qw( list ) ];
  2         11  
30             }
31              
32             my @majkeys = split( ' ', 'C Dd D Eb E F Gb G Ab A Bb B' );
33             my @minkeys = split( ' ', 'A- Bb- B- C- C#- D- Eb- E- F- F#- G- G#-' );
34              
35             sub process {
36 2     2 0 1944 my ( $self, $u, $options ) = @_;
37              
38 2   50     23 $self->{output} ||= $options->{output} || "__new__.txt";
      33        
39              
40 2         4 my $pl;
41 2         6 my $list = $self->{list};
42              
43 2 100       8 if ( defined $u->{playlist}->{name} ) {
44 1   50     5 $pl = $u->{playlist}->{name} || "";
45             }
46              
47 2         5 my $song = 0;
48 2         4 my @songs;
49              
50 2         5 foreach my $s ( @{ $u->{playlist}->{songs} } ) {
  2         7  
51 3         7 $song++;
52              
53             # Do not change key to actual.
54 3         11 local $s->{_transpose} = 0;
55              
56 3   50     22 my $key = $s->xpose($s->{key} // "C");
57 3         9 my $akey = $s->{actual_key};
58 3 50       11 if ( $akey ne '' ) {
59 0 0       0 $akey = $s->xpose( $key =~ /-$/ ? $minkeys[$akey] : $majkeys[$akey] );
60             }
61              
62 3         13 my @t = split( ' ', $s->{composer} );
63 3 50       19 @t[0,1] = @t[1,0] if @t == 2;
64             push( @songs,
65             { index => $song,
66             title =>
67             $list
68             ? sprintf("%4d: %s (%s)", $song, $s->{title}, "@t" )
69             : join( "",
70             ( $song > 1 || $pl ) ? "Song $song: " : "Song: ",
71             $s->{title},
72             " (@t)" ),
73             subtitle =>
74             join( "",
75             "Style: ", $s->{style},
76             $s->{actual_style}
77             ? ( " (", $s->{actual_style}, ")" ) : (),
78             "; key: ", $key,
79             $akey ? ( "; actual key: ", $akey ) : (),
80             $s->{actual_tempo}
81             ? ( "; tempo: ", $s->{actual_tempo} ) : (),
82             $s->{actual_repeats}
83 3 100 100     65 ? ( "; repeat: ", $s->{actual_repeats} ) : (),
    50          
    50          
    50          
    50          
    50          
84             ),
85             } );
86              
87 3 50       12 if ( $s->{transpose} ) {
88 0         0 $s->tokenize;
89 0         0 $songs[-1]->{cooked} = neatify( $s->{dataxp} );
90             }
91             else {
92 3         11 $songs[-1]->{cooked} = neatify( $s->{data} );
93             }
94             }
95              
96 2         6 my $res = "";
97 2 50 33     10 $res .= "Playlist: $pl\n" if $list && $pl;
98 2         15 foreach my $song ( @songs ) {
99 3         14 $res .= $song->{title} . "\n";
100 3 50       11 if ( $list ) {
101 0         0 next;
102             }
103 3         16 $res .= $song->{subtitle} . "\n";
104 3 100       12 $res .= "Playlist: " . $pl . "\n" if $pl;
105 3         8 $res .= "\n";
106 3         10 $res .= $song->{cooked} . "\n";
107 3         8 $res .= "\n";
108             }
109              
110 2 50       25 if ( ref( $self->{output} ) ) {
    0          
111 2         6 ${ $self->{output} } = $res;
  2         14  
112             }
113             elsif ( $self->{output} eq "-" ) {
114 0         0 binmode( STDOUT, ':utf8' );
115 0         0 print $res;
116             }
117             else {
118             open( my $fd, ">:utf8", $self->{output} )
119 0 0       0 or die( "Cannot create ", $self->{output}, " [$!]\n" );
120 0         0 print $fd ( $res, "\n" );
121 0         0 close($fd);
122             }
123             }
124              
125             sub neatify {
126 3     3 0 9 my ( $t ) = @_;
127 3         32 my @a = split( /(\<.*?\>)/, $t );
128 3         9 $t = "";
129 3         21 while ( @a > 1 ) {
130 3         12 $t .= neatify1(shift(@a));
131 3         15 $t .= shift(@a);
132             }
133 3 50       23 $t .= neatify1(shift(@a)) if @a;
134 3         18 return $t;
135             }
136              
137             sub neatify1 {
138 6     6 0 18 my ( $t ) = @_;
139             # Insert spaces and newlines at tactical places to obtain
140             # something readable and editable.
141 6         56 $t =~ s/ / _ /g;
142 6         125 while ( $t =~ s/_ +_/__/g ) {}
143 6         89 $t =~ s/([\]\}])/$1\n/g;
144 6         53 $t =~ s/([\[\{])/\n$1/g;
145 6         52 $t =~ s/([\[\{])(\*[ABCDVi]),?/$1$2 /gi;
146 6         46 $t =~ s/\n\n+/\n/g;
147 6         26 $t =~ s/^\n+//;
148 6         37 $t =~ s/^ +_/_/mg;
149 6         52 $t =~ s/_ +$/_/mg;
150 6         26 $t =~ s/\n+$/\n/;
151              
152 6         20 return $t;
153             }
154              
155             1;