%{
/***********************************************************************

Author		: Brad Slaten
              Copyright 1992
email		: cbs@sbctri.sbc.com
Date		: Thu Sep 17 08:13:29 CDT 1992
Purpose		: This is a lex(1) script that translates non ChordPro
              format songs (i.e. text with chord names above the
			  text) into ChordPro format.  It is extremely rough and
			  buggy, but it is usually better than nothing. 
SCCS ID @(#) toChord.l 1.5 Delta Date/Time: 9/17/92/08:17:41; Extraction Date/Time: 9/17/92/08:24:06 @(#)
 **********************************************************************/
#include <stdio.h>
typedef int Boolean;
char ChordBuffer[256];
char TextBuffer[256];
char* ActiveBuffer;
char* ActiveBufferPtr;
int NumChords;
int NumText;
int Initialized;
%}
Root	[A-G/]
Text	[A-Za-z]+
Number	[0-9]+
Whitespace	[ \t]
Newline	[\n]
%%
{Whitespace}	processWhiteSpace();
{Newline}	processNewline();
{Root}	processChord();
{Root}{Number}	processChord();
{Root}m	processChord();
{Root}\-	processChord();
{Root}o	processChord();
{Root}dim	processChord();
{Root}"+"	processChord();
{Root}"m"{Number}	processChord();
{Root}{Number}"+"{Number}	processChord();
{Root}{Number}\-{Number}	processChord();
{Root}{Number}b{Number}	processChord();
{Root}maj{Number}	processChord();
{Root}ma{Number}	processChord();
{Root}maj{Number}b{Number}	processChord();
{Root}min\-ma{Number}	processChord();
{Root}m{Number}b{Number}	processChord();
{Root}{Number}sus{Number}	processChord();
{Root}{Number}#{Number}	processChord();
{Root}{Number}add{Number}	processChord();
{Root}{Number}{Number}	processChord();
{Root}"#"	processChord();
{Root}"#"{Number}	processChord();
{Root}"#"m	processChord();
{Root}"#"\-	processChord();
{Root}"#"o	processChord();
{Root}"#"dim	processChord();
{Root}"#""+"	processChord();
{Root}"#""m"{Number}	processChord();
{Root}"#"{Number}"+"{Number}	processChord();
{Root}"#"{Number}\-{Number}	processChord();
{Root}"#"{Number}b{Number}	processChord();
{Root}"#"maj{Number}	processChord();
{Root}"#"ma{Number}	processChord();
{Root}"#"maj{Number}b{Number}	processChord();
{Root}"#"min\-ma{Number}	processChord();
{Root}"#"m{Number}b{Number}	processChord();
{Root}"#"{Number}sus{Number}	processChord();
{Root}"#"{Number}#{Number}	processChord();
{Root}"#"{Number}add{Number}	processChord();
{Root}"#"{Number}{Number}	processChord();
{Root}"b"	processChord();
{Root}"b"{Number}	processChord();
{Root}"b"m	processChord();
{Root}"b"\-	processChord();
{Root}"b"o	processChord();
{Root}"b"dim	processChord();
{Root}"b""+"	processChord();
{Root}"b""m"{Number}	processChord();
{Root}"b"{Number}"+"{Number}	processChord();
{Root}"b"{Number}\-{Number}	processChord();
{Root}"b"{Number}b{Number}	processChord();
{Root}"b"maj{Number}	processChord();
{Root}"b"ma{Number}	processChord();
{Root}"b"maj{Number}b{Number}	processChord();
{Root}"b"min\-ma{Number}	processChord();
{Root}"b"m{Number}b{Number}	processChord();
{Root}"b"{Number}sus{Number}	processChord();
{Root}"b"{Number}#{Number}	processChord();
{Root}"b"{Number}add{Number}	processChord();
{Root}"b"{Number}{Number}	processChord();
{Text}	processText();
{Number}	processText();
.	processText();
%%
init()
{
	if (!Initialized) {
		Initialized = 1;
		ActiveBuffer = ChordBuffer;
		ActiveBufferPtr = ActiveBuffer;
		NumChords = 0;
		NumText = 0;
	}
}

processChord()
{
	init();
	sprintf(ActiveBufferPtr,"%s",yytext);
	ActiveBufferPtr += strlen(ActiveBufferPtr);
	NumChords += strlen(yytext);
}

processText()
{
	init();
	sprintf(ActiveBufferPtr,"%s",yytext);
	ActiveBufferPtr += strlen(ActiveBufferPtr);
	NumText += strlen(yytext);
}

processWhiteSpace()
{
	init();
	sprintf(ActiveBufferPtr,"%s",yytext);
	ActiveBufferPtr += strlen(ActiveBufferPtr);
}

processNewline()
{
	init();
	/*
	sprintf(ActiveBufferPtr,"%s",yytext);
	ActiveBufferPtr += strlen(ActiveBufferPtr);
	*/
	if (NumChords > NumText) {
		/* assume a chord line */
		if (ActiveBuffer != ChordBuffer) {
			printSong(ChordBuffer,"\0");
			ChordBuffer[0] = '\0';
		}
		else {
			ActiveBuffer = TextBuffer;
		}
		ActiveBufferPtr = ActiveBuffer;
	}
	else {
		/* assume a Text line */
		if (ActiveBuffer == ChordBuffer) {
			printSong("\0",ActiveBuffer);
			ChordBuffer[0] = '\0';
		}
		else {
			printSong(ChordBuffer,TextBuffer);
			ActiveBuffer = ChordBuffer;
			ChordBuffer[0] = '\0';
			TextBuffer[0] = '\0';
		}
		ActiveBufferPtr = ActiveBuffer;
	}
	NumChords = NumText = 0;
}

printSong(chordBuffer,textBuffer)
char* chordBuffer;
char* textBuffer;
{
static Boolean ChordOpenFlag;
char* chordBufferPtr;
char* textBufferPtr;
int chordWidth;
	chordBufferPtr = chordBuffer;
	textBufferPtr = textBuffer;
	chordWidth = 0;
	while(*chordBufferPtr != '\0') {
		if (*chordBufferPtr != ' ') {
			fprintf(stdout,"[");
			while ((*chordBufferPtr != ' ') &&
					(*chordBufferPtr != '\0')) {
				fprintf(stdout,"%c",*chordBufferPtr);
				chordWidth++;
				chordBufferPtr++;
			}
			fprintf(stdout,"]");
			while ((chordWidth > 0) && (*textBufferPtr != '\0')) {
				chordWidth--;
				fprintf(stdout,"%c",*textBufferPtr);
				textBufferPtr++;
			}
			chordWidth = 0;
		}
		else {
			if (*textBufferPtr != '\0') {	
				fprintf(stdout,"%c",*textBufferPtr);
			}
			else {
				fprintf(stdout," ");
			}
			chordBufferPtr++;
			if (*textBufferPtr != '\0') {
				textBufferPtr++;
			}
		}
	}
	while(*textBufferPtr != '\0') {
		fprintf(stdout,"%c",*textBufferPtr);
		textBufferPtr++;
	}
	fprintf(stdout,"\n");
}
