
/* CRD2TEX (version 2.0) Written by Christopher Heckman, May 1997.
   This program produces a TeX version of the CHORD utility. See the file
            http://www.prism.gatech.edu/~gt7934b/Tab/software.html
   for a full description of options supported. */

#include <stdio.h>
#include <string.h>
#define LINSIZE 511
#define EOLN '\n'
#define LB '['
#define RB ']'
#define LBR "{"
#define RBR "}"

static char buffer [LINSIZE];
static FILE *input;
static lineno;

int isdigit (int);
int isspace (int);
int isupper (int);
int tolower (int);
void exit (int);


static void setchfont (s) char *s;
{
static char fname [80] = "cmti10";
char *p;

if (isdigit (*s)) for (p = fname; !isdigit (*p); p++);
else p = fname;
strcpy (p, s);
printf ("\\font\\chordfont=%s\n", fname);
}


static void settxfont (s) char *s;
{
static char fname [80] = "cmti10";
char *p;

if (isdigit (*s)) for (p = fname; !isdigit (*p); p++);
else p = fname;
strcpy (p, s);
printf ("\\font\\textfont=%s\\textfont\n", fname);
}


static int optionline (s, t) char *s, *t;
{
switch (s [1]) {
	case 'c' : case 'C' : setchfont (t); return 1; 
	case 't' : case 'T' : settxfont (t); return 1; 
	case 'A' : case 'a' : case 'd' : case 'D' : case 'G' : case 'g' : 
	case 'h' : case 'i' : case 'L' : case 'l' : case 'R' : case 'V' :
	case '2' : case '4' : 
		fprintf (stderr, "*** unimplemented option -%c ignored\n", s [1]);
		return 0; 
	case 's' : case 'o' : case 'p' : case 'x' :
		fprintf (stderr, "*** unimplemented option -%c and argument %s ignored\n", 
			s [1], t);
		return 1; 
	default :
		fprintf (stderr, "*** illegal option -%c ignored\n", s [1]);
		return 0; 
	}
}


static int braceline (fname) char *fname;
{
char *p, *q, inC = 0;

do	{
	for (p = buffer + 2; (*p != ':') && (*p != EOLN); p++);
	if ((tolower (buffer [2]) == 'o') && (tolower (buffer [3]) == 't')) {
		if (inC) puts (RBR RBR RBR); inC = 0;
		do	{
			if (!fgets (buffer, LINSIZE, input)) {
				fputs ("** file ended inside sot", stderr);
				return 0;
				}
			lineno ++;
			if ((tolower (buffer [1]) != 'e') || (*buffer != *LBR)) {
				printf ("\\hbox" LBR "\\typefont ");
				for (p = buffer; (*p != EOLN); p++)
					if (*p == ' ') printf ("\\ ");
					else if (*p == '\t') 
						printf ("\\ \\ \\ \\ \\ \\ \\ \\ ");
					else putchar (*p);
				puts (RBR "\\vskip -2pt");
				}
			} while ((tolower (buffer [1]) != 'e') || (*buffer != *LBR));
		}
	else if ((tolower (buffer [2]) == 'o') && (tolower (buffer [3]) == 'c')) {
		if (inC) puts (RBR RBR RBR); inC = 0;
		switch (tolower (buffer [1])) {
			case 's' : puts ("\\hbox" LBR "\\vrule\\vbox" LBR); break;
			case 'e' : puts (RBR RBR); break;
			default	 : fprintf (stderr, "*** unrecognized option on line %d of file %s\n",
					lineno, fname); return 0; 
			}
		}
	else if (tolower (buffer [1]) == 'n')
		if (tolower (buffer [2]) == 'g')
			fprintf (stderr, "*** {ng} ignored on line %d of file %s\n", 
					lineno, fname);
		else
			puts ("\\vfil\\eject");
	else if (*p == EOLN) return 1;
	else	{
		for (q = ++p; (*q != EOLN) && (*q != *RBR); q++);
		*q = 0;
		switch (tolower (buffer [1])) {
			case 't' :
				if (tolower (buffer [2]) == 'e') {
					for (q = buffer + 1; !isspace (*q); q++);
					settxfont (q);
					}
				else	{
					if (inC) puts (RBR); inC = 0;
					printf ("\\centerline{\\titlefont %s}\n", p);
					}
				break;
			case 's' :
				if (inC) puts (RBR); inC = 0;
				printf ("\\centerline{%s}\n", p);
				break;
			case 'c' :
				if (tolower (buffer [2]) == 'h') {
					for (q = buffer + 1; !isspace (*q); q++);
					setchfont (q);
					}
				else	{
					if (!inC) puts ("\\centerline" LBR "\\fbox" LBR "\\vbox" LBR);
					inC = 1;
					printf ("\\hbox {%s}\n", p);
					}
				break;
			default :
				fprintf (stderr, "*** unrecognized option on line %d of file %s\n",
						lineno, fname);
				return 0;
			}
		}
	if (!fgets (buffer, LINSIZE, input)) {
		if (inC) puts (RBR RBR RBR);
		return 0;
		}
	lineno ++;
	} while (*buffer == *LBR);
if (inC) puts (RBR RBR RBR);
return 1;
}


static void processfile (fname) char *fname;
{
char *p, *q, last, pmode;

if ((input = fopen (fname, "r")) == NULL) {
	fprintf (stderr, "*** can't open %s. ignoring\n", fname);
	return;
	}
for (lineno = 1; fgets (buffer, LINSIZE, input); lineno ++) {
	if (*buffer == '#') continue;
	if (*buffer == *LBR) if (!braceline (fname)) break;
	puts ("\\smallskip");
	for (q = buffer; (*q != LB) && (*q != EOLN); q++);
	if ((q == buffer) && (*q == EOLN)) {
		puts ("\\smallskip");
		continue;
		}
	printf ("\\hbox" LBR);
	if (*q != EOLN) printf ("\\vbox" LBR "\\hbox" LBR RBR "\\hbox" LBR);
	for (last = LB, p = buffer; (*p != LB) && (*p != EOLN); last = *(p++))
		if (!isspace (last) || !isspace (*p))
			putchar ((*p == '\t') ? ' ' : *p);
	puts (RBR);
	if (*p == EOLN) continue;
	puts (RBR);
	while (*p != EOLN) {
		pmode = 0;
		puts ("\\hskip -3pt\\vbox" LBR "\\vfil\\hbox" LBR "\\chordfont");
		for (p++, last = ' '; (*p != EOLN) && (*p != RB); last = *(p++))
			if (!isspace (last) || !isspace (*p))
				if (isupper (*p) || (*p == '/')) {
					if (pmode) printf (RBR "$");
					pmode = 0;
					putchar (*p);
					}
				else	{
					if (!pmode) printf ("$^" LBR "\\chordfont ");
					pmode = 1;
					if (*p == 'b') 
						if (*(p + 1) == '/') printf ("\\flat");
						else printf ("\\flat ");
					else if (*p == '#')
						if (*(p + 1) == '/') printf ("\\sharp");
						else printf ("\\sharp ");
					else putchar (*p);
					}
		if (*p == EOLN) {
			fprintf (stderr, "*** line %d of file %s ends in chord\n",
					lineno, fname);
			continue;
			}
		if (pmode) printf (RBR "$");
		printf ("\\hskip 0.1in " RBR "\\vskip -2pt\\hbox" LBR);
		for (p++, last = ' '; (*p != LB) && (*p != EOLN); last = *(p++))
			if (!isspace (last) || !isspace (*p))
				if (*p != '_') putchar (*p);
				else printf ("\\vbox{\\hbox{\\phantom{X}}\\hrule}");
		puts (RBR RBR);
		}
	puts (RBR);
	}
puts ("\\vfil\\eject"); fclose (input);
}


int main (argc, argv) int argc; char *argv[];
{
int i;

puts ("\\def\\fbox#1{\\vbox{\\hrule\\hbox{\\vrule\\kern3pt\\vbox{\\kern3pt#1"
	"\\kern3pt}\\kern3pt\\vrule}\\hrule}}\n\\font\\titlefont=cmr15\n"
	"\\nopagenumbers\n\\font\\typefont=cmtt10\\vsize=10.5in\n"
	"\\voffset=-0.75in");
settxfont ("cmr10");
setchfont ("cmti10");
for (i = 1; i < argc; i++)
	if (argv [i][0] != '-') processfile (argv [i]);
	else if (i < argc - 1) i += optionline (argv [i], argv [i + 1]);
	else fprintf (stderr, "*** option -%c at end of command list ignored.\n",
			argv [i][1]);
puts ("\\end");
return 0;
}
		
					


