App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/A2Crd.pm view on Meta::CPAN
my $n_chords=0 ;
my $n_words=0 ;
#print("CL:") ; # JJW, uncomment for debugging
foreach (@words) {
if (length $_ > 0) {
$n_words++ ;
my $is_chord = ChordPro::Chords::parse_chord($_) ? 1 : 0 ;
if(! $is_chord) {
if(generic_parse_chord($_)) {
print STDERR "$_ detected by generic, not internal parse_chord\n" if $local_debug ;
$is_chord=1 ;
}
}
$n_chords++ if $is_chord ;
print STDERR " ($is_chord:$_)" if $local_debug ;
#print(" \'$is_chord:$_\'") ; # JJW, uncomment for debugging
}
}
print STDERR "\n" if $local_debug ;
return '_' if $n_words == 0 ; # blank line, redundant logic with sub classify(), but makes this more robust to changes in classify() ;
my $type = $n_chords/$n_words > 0.4 ? 'c' : 'l' ;
if($type eq 'l') {
# is it likely the line had a lot of unknown chords, check
# the ratio of total chars to nonblank chars , if it is large then
# it's probably a chord line
# $type = 'c' if $n_words > 1 && $n_tot_chars/$n_nonblank_chars > 2. ;
}
#print(" --- ($n_chords/$n_words) = $type\n") ; # JJW, uncomment for debugging
return $type ;
}
# reformat an input line classified as a comment for the chordpro format
sub format_comment_line
{
my $line = $_[0] ;
# remove [] from original comment
$line =~ s/\[// ;
$line =~ s/\]// ;
return '' if $line eq '' ;
return "{comment: " . $line . "}" ;
}
# Process the lines via the map.
my $infer_titles;
sub maplines {
my ( $map, $lines ) = @_;
my @out;
$infer_titles = $config->{a2crd}->{'infer-titles'}
&& !$options->{fragment};
# Preamble.
# Pass empty lines.
print STDERR "====== _C =====\n" if $local_debug ;
print STDERR "MAP: \'$map\' \n" if $local_debug ;
while ( $map =~ s/^([_C])// ) {
print STDERR "$1 == @{$lines}[0]\n" if $local_debug ;
# simply output blank or comment lines at the start of the file
# but don't count the line as possible title
my $pre = ($1 eq "C" ? "{comment:" : "" ) ;
my $post = ($1 eq "C" ? "}" : "" ) ;
push( @out, $pre . shift( @$lines ) . $post );
}
print STDERR "====== infer title =====\n" if $local_debug ;
# Infer title/subtitle.
if ( $infer_titles && $map =~ s/^l// ) {
push( @out, "{title: " . shift( @$lines ) . "}");
if ( $map =~ s/^l// ) {
push( @out, "{subtitle: " . shift( @$lines ) . "}");
}
}
print STDERR "====== UNTIL chords or tablature =====\n" if $local_debug ;
# Pass lines until we have chords or tablature
while ($map =~ /^(.)(.)(.)/) {
push @out, "ULC $map" if $local_debug ;
# some unusual situations to handle,
# cl. => exit this loop for normal cl processing
# .t => exit the loop
# l.t or c.t => output the l or c as comment, then exit the loop
# [_f{C].. => output the blank, fingering,directive or comment, and continue the loop
# we have to stop one line before tablature, in case the line before the tablature needs to be included in the
# tablature itself
print STDERR "$1 == @{$lines}[0]\n" if $local_debug ;
last if($1 eq "c" && $2 eq "l") ;
last if($2 eq "t" ) ;
if(($1 eq "c" || $1 eq "l") && $3 eq "t") {
push @out, format_comment_line(shift(@$lines)) ;
$map =~ s/.// ;
last ;
}
# in the remaining cases, output the line (properly handled), and continue the loop
if ( $1 eq "l" or $1 eq "C") {
push @out, format_comment_line(shift(@$lines)) ;
}
elsif ( $1 eq "f" ) {
foreach my $fchart (decode_fingering(shift( @$lines ),1) ) {
push( @out, $fchart);
}
}
elsif ( $1 eq "{" ) {
( run in 0.831 second using v1.01-cache-2.11-cpan-b16cb0d3907 )