#!/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
   <a href="mailto:jc@trillian.mit.edu">John Chambers</a>
=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 = <F>) {
		$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 .= <F>;
	}
	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;
}
