File Coverage

blib/lib/Data/iRealPro/Output/Text.pm
Criterion Covered Total %
statement 82 90 91.1
branch 21 36 58.3
condition 8 15 53.3
subroutine 12 12 100.0
pod 0 4 0.0
total 123 157 78.3


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 Jan 15 10:38:42 2019
9             # Update Count : 106
10             # Status : Unknown, Use with caution!
11              
12             ################ Common stuff ################
13              
14 4     4   4566 use strict;
  4         8  
  4         119  
15 4     4   21 use warnings;
  4         8  
  4         98  
16 4     4   18 use Carp;
  4         7  
  4         185  
17 4     4   1803 use utf8;
  4         48  
  4         20  
18              
19             package Data::iRealPro::Output::Text;
20              
21 4     4   204 use parent qw( Data::iRealPro::Output::Base );
  4         10  
  4         38  
22              
23 4     4   216 use Data::iRealPro::URI;
  4         7  
  4         85  
24 4     4   20 use Data::iRealPro::Playlist;
  4         9  
  4         71  
25 4     4   18 use Data::iRealPro::Song;
  4         7  
  4         4570  
26              
27             sub options {
28 3     3 0 7 my $self = shift;
29 3         6 [ @{ $self->SUPER::options }, qw( list ) ];
  3         17  
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 3     3 0 3093 my ( $self, $u, $options ) = @_;
37              
38 3   50     33 $self->{output} ||= $options->{output} || "__new__.txt";
      33        
39              
40 3         6 my $pl;
41 3         10 my $list = $self->{list};
42              
43 3 100       11 if ( defined $u->{playlist}->{name} ) {
44 1   50     4 $pl = $u->{playlist}->{name} || "";
45             }
46              
47 3         7 my $song = 0;
48 3         8 my @songs;
49              
50 3         6 foreach my $s ( @{ $u->{playlist}->{songs} } ) {
  3         12  
51 4         8 $song++;
52              
53             # Do not change key to actual.
54 4         12 local $s->{_transpose} = 0;
55              
56 4   50     25 my $key = $s->xpose($s->{key} // "C");
57 4         10 my $akey = $s->{actual_key};
58 4 100       13 if ( $akey ne '' ) {
59 1 50       8 $akey = $s->xpose( $key =~ /-$/ ? $minkeys[$akey] : $majkeys[$akey] );
60             }
61              
62 4         18 my @t = split( ' ', $s->{composer} );
63 4 50       25 @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 4 100 100     80 ? ( "; repeat: ", $s->{actual_repeats} ) : (),
    50          
    50          
    100          
    50          
    50          
84             ),
85             } );
86              
87 4 50       13 if ( $s->{transpose} ) {
88 0         0 $s->tokenize;
89 0         0 $songs[-1]->{cooked} = neatify( $s->{dataxp} );
90             }
91             else {
92 4         17 $songs[-1]->{cooked} = neatify( $s->{data} );
93             }
94             }
95              
96 3         8 my $res = "";
97 3 50 33     13 $res .= "Playlist: $pl\n" if $list && $pl;
98 3         17 foreach my $song ( @songs ) {
99 4         26 $res .= $song->{title} . "\n";
100 4 50       22 if ( $list ) {
101 0         0 next;
102             }
103 4         15 $res .= $song->{subtitle} . "\n";
104 4 100       21 $res .= "Playlist: " . $pl . "\n" if $pl;
105 4         11 $res .= "\n";
106 4         12 $res .= $song->{cooked} . "\n";
107 4         12 $res .= "\n";
108             }
109              
110 3 50       29 if ( ref( $self->{output} ) ) {
    0          
111 3         7 ${ $self->{output} } = $res;
  3         21  
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 4     4 0 10 my ( $t ) = @_;
127 4         42 my @a = split( /(\<.*?\>)/, $t );
128 4         11 $t = "";
129 4         27 while ( @a > 1 ) {
130 4         17 $t .= neatify1(shift(@a));
131 4         25 $t .= shift(@a);
132             }
133 4 50       21 $t .= neatify1(shift(@a)) if @a;
134 4         22 return $t;
135             }
136              
137             sub neatify1 {
138 8     8 0 18 my ( $t ) = @_;
139             # Insert spaces and newlines at tactical places to obtain
140             # something readable and editable.
141 8         65 $t =~ s/ / _ /g;
142 8         197 while ( $t =~ s/_ +_/__/g ) {}
143 8         96 $t =~ s/([\]\}])/$1\n/g;
144 8         67 $t =~ s/([\[\{])/\n$1/g;
145 8         69 $t =~ s/([\[\{])(\*[ABCDVi]),?/$1$2 /gi;
146 8         45 $t =~ s/\|N(\d)/|N$1 /g;
147 8         54 $t =~ s/\n\n+/\n/g;
148 8         34 $t =~ s/^\n+//;
149 8         54 $t =~ s/^ +_/_/mg;
150 8         77 $t =~ s/_ +$/_/mg;
151 8         34 $t =~ s/\n+$/\n/;
152              
153 8         33 return $t;
154             }
155              
156             1;