#!/usr/local/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; $P =~ s"^.*/""; $V = $ENV{"V_$P"} || 1; $X = 0; # Number of tunes we've seen so far. $files = 0; # Number of files read so far. $numtitles = 8; # Whether to show all titles on P line print STDERR "$0: P=$P V=$V\n" if $V>0; for $arg (@ARGV) { if (($flg,$a,$rest) = ($arg =~ /^([-+])(.)(.*)/)) { if (uc($a) eq 'A') { # Joining first tunes if ($rest =~ /^(\d+)/) {$v = $1} else {$v = 1} $numtitles = ($flg eq '+') ? $v : 0; # Join first and second "tunes" print STDERR " numtitles=$numtitles [init]\n" if $V>1; } elsif (uc($a) eq 'J') { # Joining first tunes $join = $X = ($flg eq '+'); # Join first and second "tunes" } elsif (uc($a) eq 'S') { # Generate separators. $sep = ($flg eq '+') ? 1 : 0; } } elsif (-f $arg) { push @files, $arg; } elsif ($arg =~ /^M:(.*)/) { $Mhdr = $1; } elsif ($arg =~ /^L:(.*)/) { $Lhdr = $1; } elsif (!$Title) { $Title = $arg; } else { print STDERR "$0: Unknown arg \"$arg\" ignored.\n"; } } $Title = 'Medley' unless defined $Title; ($hdr1 = "$Title.hdr") =~ s/\s+//g; ($hdr2 = "hdr/$Title.hdr") =~ s/\s+//g; print "Exists: $hdr1\n" if -f $hdr1 && $V>1; print "Exists: $hdr2\n" if -f $hdr2 && $V>1; if ( -f ($hdr = $hdr1) || -f ($hdr = $hdr2)) { # Header file exists in current dir? open(T,$hdr) || die "$0: 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 "$0: Can'd read \"$file\" [$!]\n"; next file; } $Tcnt = 0; 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 ++$Tcnt; # Count the titles } elsif ($Tcnt < $numtitles) { print STDERR " Tcnt=$Tcnt numtitles=$numtitles [P:]\n" if $V>1; $P{$X} .= " ($Ttl)"; $T .= " ($Ttl)"; # Convert to part name ++$Tcnt; # Count the titles } 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";