#!/usr/bin/perl
=head1 NAME
abc2bars
=head1 SYNOPSIS
abc2bars "title" [file]... >foo.abc
=head1 DESCRIPTION
This program reads through the input file(s), or stdin if no files
are named, looking for abc tunes. When it finds one, it outputs the
first two bars of the tune, with the tune name in the place of the
first "guitar chord". Other chords are deleted.
The resulting file can be fed to abc2ps or abcmtex to produce a
page of musical reminders of how the tunes start.
Tunes will be in the same order they are in the files. Alphabetical
order is recommended, but any organization that makes sense to you
may be used.
The output contains abc2ps commands that will produce very small
music and names.
=head1 BUGS
If a tune contains no L: line, there will be none in the output,
and the L: line from the preceding tune will be used. This isn't
always what you want. Fix: Include L: lines in all your tunes, even
when they aren't needed.
The T:, L: and K: lines must be at the start of a line to be
recognized.
=head1 AUTHOR
John Chambers
=cut
$title = shift || "Tunes";
print "%%scale 0.4\n";
print "%%maxshrink 1\n";
print "%%staffwidth 16.0cm\n";
print "%%leftmargin 2.0cm\n";
print "%%topmargin 0.2cm\n";
print "%%topspace 0.2cm\n";
print "%%titlespace 0.0cm\n";
print "%%composerspace 0.0cm\n";
print "%%musicspace 0.0cm\n";
print "%%staffsep 40\n";
print "%%maxshrink 1\n";
print "%%maxshrink 1\n";
print "%%maxshrink 1\n";
$min = 12; # Min number of notes required.
$page = 0; # Page counter, for titles.
$tunes = 0; # Tune counter, for page eject.
$tpp = 105; # Max tunes per page.
#$tpk = 50; # Max tunes per kludge.
sub ttl {
++ $page;
print "\n";
print "X: $page\n";
print "T: $title p.$page\n";
print "K: C\n";
}
$| = 1;
$t = 0;
$s = 0; # State
for $f (@ARGV) {
if (!open(F,$f)) {
print STDERR "$0: Can't read \"$f\" [$!]\n";
next;
}
while ($l = ) {
$l =~ s/\s+$//;
if ($l =~ /^T:\s*(.*)/) {
$T[$t++] = $1;
$s = 1; # State: in header.
} elsif ($l =~ /^X:\s*\d+/) {
$s = 1; # State: in header.
$t = 0; # Start over with new title.
} elsif ($l =~ /^L:\s*([\d\/]+)/) {
$L = $1;
} elsif ($l =~ /^K:\s*([\w\^_=]+)/) {
if ($s == 1) {
$K = $1;
$s = 2; # State: in music.
}
} elsif ($l =~ /^[A-Z]:/) {
} elsif ($l =~ /^%/) {
} elsif ($s == 2) {
if ($m = &strip($l)) { # Do we have a line of music?
if (($tunes % $tpp) == 0) {
&ttl;
# } elsif (($tunes % $tpk) == 0) {
# print "P:\n";;
}
$tunes ++;
$ttl = $T[0];
print "K:$K\\\n";
print "L:$L\\\n";
print "[|\"$ttl\"$m |]\n";
$s = 3; # State: Done with this tune.
$t = 0; # Start over with new title.
}
}
}
}
exit 0;
sub strip {
local($l) = @_;
local($b,$m,$n) = (1,'',0);
while ($l =~ m"\\+\s*$") { # Continued?
$l =~ s"\s*\\+\s*$" ";
$l .= ;
}
while ($l) {
if ($l =~ s'^\s+'') { # White space?
$m = $m . ' ' if $m; # Convert to single space.
} elsif ($l =~ s'^"[^"]*"'') { # Discard a chord.
} elsif ($l =~ s'^([\w\/\^_=\',])'') { # Note?
$m = $m . $1; ++$n;
} elsif ($l =~ s/^(\[\||\|\]|:*\|+:*)//) { # Bar line?
return $m if ($b >= 2 && $n >= $min);
if ($n) {$m = $m . $1; ++$b}
} elsif ($l =~ s/^\[([^]]*)\]//) { # Chord?
$m = $m . "[$1]"; ++$n;
} elsif ($l =~ s/^(.)//) { # Anything else
$m = $m . $1;
}
}
$m;
}