#!/usr/bin/perl # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # #DESCRIPTION # abcjoin - combine ABC files # #SYNOPSIS # abcjoin file... # #DESCRIPTION # Join a list of ABC files into a single file. The tunes will be # separated by a blank line, and will be numbered consecutively if # they don't have distinct X: index numbers already. # # The result is written to standard output. # #OPTIONS # # +H # Incorporate the header file . If it exists, we will read # it in, and we will also generate %% directives that tell abc2ps # to center its title and then put subsequent titles at the left. # # +R # Renumber the tunes. # The tunes will be renumbered consecutively, starting from X:1. # The default is -R, which also renumbers, but only when the # input X: indexes aren't increasing. So if the input tunes are # already numbered in increasing order, the default will use # their numbers. # # +S # Generate separator lines. # This is done with the abc2ps %%sep directive. At present, there # is no way to specify the parameters. # #BUGS # The output X: numbers will be distinct. This is a feature. # # We never read from standard input. Maybe we should add an option # to do this. # #AUTHOR # John Chambers http://trillian.mit.edu/~jc/ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # $| = 1; $V = 1; $Xlast = -1; for $f (@ARGV) { &outtune("#$0: arg='$f'") if $V>3; if (($flg,$opts) = ($f =~ /^([-+])(.*)/i)) { &outtune("#$0: flg=$flg' opts='$opts'") if $V>2; while ($opts =~ s/^(.)//) { $opt = uc($1); &outtune("#$0: opt='$opt'") if $V>2; if ($opt eq 'S') { $sep = ($flg eq '+') ? 1 : 0; # Generate separators. &outtune("#$0: sep=$sep.") if $V>1; } elsif ($opt eq 'H') { $hopt = ($flg eq '-') ? 0 : 1; # Look for header file. &outtune("#$0: hopt=$hopt.") if $V>2; if (open(F,$opts) # Look for the header file. || open(F,"hdr/$opts.hdr") || open(F,"$opts.hdr")) { # Can we read it? $hfile = 1; &onefile(); # Copy it to output. $hfile = 0; $opts = ''; } else { print STDERR "#$0: Can't read \"$opts\" ($!)\n" if $V>1; } } elsif ($opt eq 'N' || $opt eq 'R') { $ren = ($flg eq '+') ? 1 : 0; # Renumber the tunes. &outtune("#$0: ren=$ren.") if $V>2; } else { print STDERR "#$0: Unknown option '$opt'\n" if $V>0; } } } elsif (open(F,$f)) { if ($last && $files) { &outtune("") unless $hopt; } &onefile(); } else { print STDERR "#$0: Can't read \"$f\" [$~]\n"; } } exit 0; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # Read one file and copy it to output. It must be the file F. # sub onefile { local($l,$T,$X); $last = ''; for $l () { $l =~ s/\s+$//;; # Trim trailing white space if ($l || $last) { $l =~ s/^(\w:)\s*/$1 /; # Adjust spacing after : if ($l =~ /^X:\s*(\d+)/) { # X: line $X = $1; $Xnext = $ren ? 1 : $X; # The input tune's number, if renumbering &outtune("% Xnext=$Xnext Xlast=$Xlast") if $V>3; if ($Xnext <= $Xlast) {$Xnext = $Xlast + 1} &outtune("% Xnext=$Xnext Xlast=$Xlast") if $V>2; &outtune("\n%%sep 0 1 500") if $sep && $tunes; $l = "X: $Xnext"; &outtune("\n$l") unless $hopt && $tunes; ++$tunes; $Xlast = $Xnext; # Remember this tune index } elsif ($l =~ /^T:\s*(.+)/) { # T: line if (!defined($X)) { $X = 0; &outtune("\nX: 0"); } &outtune("%T $1") if $V>2; if (!defined($T) || (!$hopt) || $hfile) { &outtune("% Copy title because T not defined.") if !defined($T) && $V>2; &outtune("% Copy title in header file.") if $hfile && $V>2; &outtune("% Copy title because no H option.") if !$hopt && $V>2; $T = $1; # Only do first title for non-header files. if ($hfile || !$hopt) { &outtune("T: $T"); # Use regular title line. } else { &outtune("P: $T"); # Convert title to "part" name. } } } else { &outtune("$l"); } } $last = $l; } ++$files; } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # sub outtune { local($l); for $l (@_) { $l = '%' if $hopt && !$l; print "$l\n"; } }