#!/usr/bin/perl -w =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, so 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. This is always a good idea anyway. The T:, L: and K: lines must be at the start of a line to be recognized. =head1 AUTHOR John Chambers jc:trillian.mit.edu =cut $| = 1; ($P = $0) =~ s".*/""; # Our name, minus directories $V = $ENV{"V_$P"} || 1; # Verbose/trace/debug level $exitstat = 0; # Set to nonzero for failure $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 "%%scale 0.4\n"; $minbars = 2; # Number of bars per tune $minnotes = 11; # Min number of notes required $page = 0; # Page counter, for titles $tunes = 0; # Tune counter, for page eject $tpp = 128; # Max tunes per page $tps = 4; # Number of tunes per staff $| = 1; $t = 0; $s = 0; # State for $f (@ARGV) { if (!open(F,$f)) { print STDERR "$0: Can't read \"$f\" [$!]\n"; next; } $eol = "\\\n"; 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? $tunes ++; if (($tunes % $tpp) == 1) { &ttl(); } elsif ($tps && ($tunes % $tps) == 0) { # print "%[EOL after $tunes tunes]\n"; $eol = "\n"; } $ttl = $T[0]; print "[K:$K]\\\n"; print "[L:$L]\\\n"; $m =~ s/- \|$/ |/; # Suppress final ties print "[|\"$ttl\"$m]$eol"; $s = 3; # State: Done with this tune $t = 0; # Start over with new title print "P:\n" if $eol eq "\n"; $eol = "\\\n"; } } } } while ($tunes % $tps) { print "y8 y8 y8 y8 y8 y8\\\n"; ++$tunes; } exit $exitstat; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # sub strip { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # local($line) = @_; local($bars,$music,$notes,$x) = (0,'',0); $line = '' unless defined $line; while ($line =~ m/\\[r\s]*$/) { # Continued? $line =~ s/\s*\\[r\s]*$/ /; if ($x = ) { $line .= $x; # Append next line } else { print STDERR "$P/strip: EOF in \"$f\"\n" if $V>1; } } unless ($line) { print STDERR "$P/strip: EOF in \"$f\"\n" if $V>0; return $line; } while ($line) { if ($line =~ s'^\s+'') { # White space? $music = $music . ' ' if $music; # Convert to single space } elsif ($line =~ s'^"[^"]*"'') { # Discard a chord } elsif ($line =~ s'^{[^}]*}'') { # Discard grace notes } elsif ($line =~ s'^([A-Ga-g][\d\/\^_=\',]*)'') { # Note? $music = $music . $1; ++$notes; # $music .= "[$notes]"; } elsif ($line =~ s/^(\[\||\|\]|:*\|+:*)//) { # Bar line? if ($notes) { $music = $music . '|'; ++$bars } return $music if (($bars >= $minbars) && ($notes >= $minnotes)); } elsif ($line =~ s/^\[([^]]*)\]//) { # Chord? $music = $music . "[$1]"; ++$notes; # $music .= "[$notes]"; } elsif ($line =~ s/^(.)//) { # Anything else $music = $music . $1; } } $music; # Ran off end of line } sub ttl { # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ++ $page; print "\n"; print "X: $page\n"; print "T: $title p.$page\n"; print "K: C\n"; print "%\n"; }