#!/usr/bin/perl # #NAME # abcmedley - combine abc tunes into medley page # #SYNOPSIS # abcmedley "Title" file.. # #DESCRIPTION # Read a list of abc files (or passage from stdin), and write output that is # a titled medley. The title will be at the top of the first page, and the # titles of the tunes will be converted to part names. Also, we modify the # X: lines, making an X:1 title section plus sequentially numbered X: parts. # # If the title is the name of a file, it will be read and used for the X:1 # part of the medley. It probably shouldn't contain music. If the title # isn't a file name, we will generate an X:1 initial portion of the output # with the minimum needed to satisfy abc2ps. # # We then read the tune files, converting their T: titles to P: part names. # Only the first title will be used, because abc2ps refuses to print # multiple part names for a single tune. # #HEADERS # As a special kludge, you may include M and L header fields on the command # line, and they will override the corresponding lines in the files. This is # mostly used to convert between C| and 2/4 time. # #AUTHOR # John Chambers $| = 1; ($P = $0) =~ s"^.*/""; $V = $ENV{"V_$P"} || 1; print "\%$P: V=$V.\n" if $V>1; $X = 0; # Number of tunes we've seen so far. $files = 0; # Number of files read so far. $titles = 0; # How many titles to show (0=all) for $arg (@ARGV) { if (($flg,$a) = ($arg =~ /^([-+])(.*)/)) { print "\%$P: flg=\"$flg\" a=\"$a\"\n" if $V>1; $A = uc($a); print "\%$P: flg=\"$flg\" A=\"$A\"\n" if $V>2; if ($A eq 'A') { # Joining first tunes (obsolete?) $alltitles = ($flg eq '+'); # Join first and second "tunes" } elsif ($A eq 'J') { # Joining first tunes $join = $X = ($flg eq '+'); # Join first and second "tunes" } elsif ($A eq 'S') { # Generate separators. $sep = ($flg eq '+') ? 1 : 0; } elsif ($A =~ /^T(\d*)$/) { # Number of titles $titles = int($1) || 0; print "\%$P: $titles titles.\n" if $V>1; } elsif ($A =~ /^V(\d*)$/) { # Verbose level $V = int($1) || $V++; print "\%$P: V=$V.\n" if $V>1; } else { print STDERR "$P: Arg \"$a ('$flg'+'$A') not recognized.\n" if $V>0; } } elsif (-f $arg) { push @files, $arg; } elsif ($arg =~ /^M:(.*)/) { $Mhdr = $1; } elsif ($arg =~ /^L:(.*)/) { $Lhdr = $1; } elsif (!$Title) { $Title = $arg; } else { print STDERR "$P: Unknown arg \"$arg\" ignored.\n"; } } $Title = 'Medley' unless defined $Title; ($hdr1 = "$Title.hdr") =~ s/\s+//g; ($hdr2 = "hdr/$Title.hdr") =~ s/\s+//g; print STDERR "Exists: $hdr1\n" if -f $hdr1 && $V>1; print STDERR "Exists: $hdr2\n" if -f $hdr2 && $V>1; if ( -f ($hdr = $hdr1) || -f ($hdr = $hdr2)) { # Header file exists? open(T,$hdr) || die "$P: Can't read \"$hdr1\" [$!]\n"; while ($l = ) { $l =~ s/[\s\r]*$//; if ($join) { if ($l =~ /^X:/) { print "X: 1\n"; } elsif ($l) { print "$l\n"; } } else { print "$l\n";; } } } else { print "X: $X\n"; # Generate title lines. print "T: $Title\n"; print "K: C\n\n"; } ++$tunes; $files = 1; file: for $file (@files) { unless (open(F,$file)) { print STDERR "$P: Can'd read \"$file\" [$!]\n"; next file; } $Tcount = 0; # Title count for this tune line: for $line () { if ($line) { if ($line =~ s/^(X:\s*)(\d*)\s*//) { if ($2 > $X) {$X = $2} else {++$X} # New part encountered. if ($join) { --$join; } else { print "\n%%sep 0 1 500\n" if $sep && $tunes; print "\nX: $X\n"; ++$tunes; } next line; } elsif ($line =~ /^(T:)\s*(.*)/) { # Title. ($Ttl = $2) =~ s/(\w)/\U$1/; if (!$P{$X}) { $P{$X} = $Ttl; $T = "P: $Ttl"; # Convert to part name. $Tcount++; # Count the titles used print "\%$P: Title $Tcount of $titles ($Ttl)\n" if $V>1; } elsif ($titles == 0 || $Tcount < $titles) { $P{$X} .= " ($Ttl)"; $T .= " ($Ttl)"; # Convert to part name. $Tcount++; # Count the titles used print "\%$P: Title $Tcount of $titles ($Ttl)\n" if $V>1; } next line; } elsif ($line =~ /^(M:)\s*(.*)/) { $line = "M:$Mhdr\n" if $Mhdr; } elsif ($line =~ /^(L:)\s*(.*)/) { $line = "L:$Lhdr\n" if $Lhdr; } else { if ($T) {print "$T\n"; $T = ''} } print $line; } } } print "\n";