/*  
 *  This file is part of abc2ps, Copyright (C) 1996,1997 Michael Methfessel
 *  See file abc2ps.c for details.
 */

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string.h>
#ifdef _MSVC
#include <process.h>
#endif
#include <ctype.h>
#include "abc2ps.h"

/*  subroutines connected with page layout  */

/* ----- fontspec ----- */
static void fontspec(struct FONTSPEC *f,
		     char name[],
		     float size)
{
	strcpy(f->name, name);
	f->size = size;
}

/* ----- add_font ----- */
/* checks font list, adds font if new */
static int add_font(struct FONTSPEC *f)
{
	int i,i0,fnum;

	i0=-1;
	for (i=0;i<nfontnames;i++) {
		if (!strcmp(f->name,fontnames[i]))
			i0=i;
	}

	if (i0>=0) {
		fnum=i0;
		if (vb>=10)
			printf("Already at %d: font %s\n",fnum,f->name);
	} else {
		fnum=nfontnames;
		strcpy(fontnames[fnum],f->name);
		if (vb>=10)
			printf("Add new at %d: font %s\n",fnum,f->name);
		nfontnames++;
	}
	return fnum;
}

/* ----- make_font_list ----- */
void make_font_list(struct FORMAT *f)
{
	if (vb>=10)
		printf ("Adding fonts from format..\n");
	add_font(&f->titlefont);
	add_font(&f->subtitlefont);
	add_font(&f->composerfont);
	add_font(&f->partsfont);
	add_font(&f->vocalfont);
	add_font(&f->textfont);
	add_font(&f->wordsfont);
	add_font(&f->gchordfont);
	add_font(&f->BookTitleFont);
	add_font(&f->CopyrightFont);
	add_font(&f->StrTabFont);
	add_font(&f->SourceFont);
	add_font(&f->DcDsFont);
	add_font(&f->DynFont);
	add_font(&f->InfoFont);
	add_font(&f->HistoryFont);
}

/* ----- set_standard_format ----- */
void set_standard_format(struct FORMAT *f) {
	int i;

	strcpy(f->name, "standard");
	if (vb>=10) printf("Loading format \"%s\"\n",f->name);
	f->BookTitle[0]		=	'\0';
	f->BookCR[0]		=	'\0';
	f->pageheight		=	PAGEHEIGHT * IN;
	f->staffwidth		=	STAFFWIDTH * IN;
	f->leftmargin		=	LEFTMARGIN * IN;
	f->MirrorIndent		=	MIRRORINDENT * IN;
	f->topmargin		=	(float)1.0  * CM;
	f->botmargin		=	(float)1.0  * CM;
	f->topspace			=	(float)0.8  * CM;
	f->titlespace 		=	(float)0.2  * CM;
	f->subtitlespace	=	(float)0.1  * CM;
	f->composerspace	=	(float)0.2  * CM;
	f->musicspace		=	(float)0.2  * CM;
	f->partsspace		=	(float)0.3  * CM;
	f->staffsep			=	(float)46.0 * PT;
	f->vocalspace		=	(float)23.0 * PT;
	f->textspace		=	(float)0.5  * CM;
	f->wordsspace		=	(float)0.0  * CM;
	f->LineSep			=	(float)8.0 * PT;
	f->DecoSpacing		=	(float)2.0 * PT;
	f->scale			=	(float)0.70;
	f->maxshrink		=	(float)0.65;
	f->landscape		=	0;
	f->titleleft		=	0;
	f->stretchstaff		=	1;
	f->stretchlast		=	0;
	f->continueall		=	0;
	f->breakall			=	0;
	f->writehistory		=	0;
	f->withxrefs		=	0;
	f->oneperpage		=	0;
	f->PageNumTop		=	0;
	f->PageMirror		=	0;
	f->ShowTempo		=	1;
	f->ShowSource		=	1;
	f->ShowRhythm		=	1;
	f->ShowHistory		=	1;
	f->ShowTrans		=	1;
	f->CombineVoices	=	0;
	f->CarryAccs		=	0;
	f->HelperAccs		=	0;
	f->Watermark		=	0;
	f->WatermarkFile	=	0;
	f->WatermarkDate	=	0;
	f->NoInlineFmt		=	0;
	f->RollsClose		=	1;
	f->BreathsClose		=	1;
	f->ManualPages		=	0;
	f->MirrorIndent		=	(float)0.5 * IN;
	f->FreeMetStyle		=	1;
	f->musiconly		=	0;
	f->titlecaps		=	0;
	f->barsperstaff		=	0;
	f->lineskipfac		=	(float)1.1;
	f->parskipfac		=	(float)0.4;
	f->StrTabSpace		=	(float)1.5;
	f->StaffTextHFac	=	(float)0.5;
	f->StaffTextVFac	=	(float)0.333;
	f->NoteTextFac		=	(float)0.5;
	f->WatermarkGray	=	(float)0.85;
	fontspec(&f->titlefont,		"Times-Roman",		15.0);
	fontspec(&f->subtitlefont,	"Times-Roman",		12.0);
	fontspec(&f->composerfont,	"Times-Italic",		11.0);
	fontspec(&f->partsfont,		"Times-Roman",		11.0);
	fontspec(&f->tempofont,		"Times-Bold",		10.0);
	fontspec(&f->vocalfont,		"Times-Bold",		13.0);
	fontspec(&f->textfont,		"Times-Roman",		12.0);
	fontspec(&f->wordsfont,		"Times-Roman",		12.0);
	fontspec(&f->gchordfont,	"Helvetica",		12.0);
	fontspec(&f->BookTitleFont, "Helvetica-Bold",	12.0);
	fontspec(&f->CopyrightFont, "Helvetica-Italic", 10.0);
	fontspec(&f->SourceFont,	"Helvetica-Italic", 10.0);
	fontspec(&f->StrTabFont,	"Times-Roman",		14.0);
	fontspec(&f->InfoFont,		"Helvetica",		11.0);
	fontspec(&f->HistoryFont,	"Helvetica",		10.0);
	for (i = 0; i < MAXVOICE; i++) {
		f->NoDecos[i] = FALSE;
		f->DecosBelow[i] = FALSE;
	}

	/* These objects can't be modified by the user. */
	fontspec(&f->DcDsFont,		"Times-Bold",		12.0);
	fontspec(&f->DynFont,		"Times-BoldItalic", 11.0);

	/* These objects should only be modifed using %% switches in the source. */
	f->InlineSyntax[0] = f->Syntax[0] = '\0';
}

/* ----- set_pretty_format ----- */
void set_pretty_format(struct FORMAT *f) {
	int i;

	strcpy (f->name, "pretty");
	if (vb>=10) printf("Loading format \"%s\"\n",f->name);
	f->BookTitle[0] = '\0';
	f->BookCR[0] = '\0';
	f->pageheight 	    =	PAGEHEIGHT * IN;
	f->staffwidth 	    =	STAFFWIDTH * IN;
	f->leftmargin 	    =	LEFTMARGIN * IN;
	f->MirrorIndent		=	MIRRORINDENT * IN;
	f->topmargin	    =	(float)1.0  * CM;
	f->botmargin	    =	(float)1.0  * CM;
	f->topspace			=	(float)0.8  * CM;
	f->titlespace 	    =	(float)0.4  * CM;
	f->subtitlespace    =	(float)0.1  * CM;
	f->composerspace    =	(float)0.25 * CM;
	f->musicspace 	    =	(float)0.25 * CM;
	f->partsspace 	    =	(float)0.3  * CM;
	f->staffsep			=  (float)50.0  * PT;
	f->vocalspace 	    =  (float)23.0  * PT;
	f->textspace	    =	(float)0.5  * CM;
	f->wordsspace 	    =	(float)0.0  * CM;
	f->LineSep			=	(float)8.0 * PT;
	f->DecoSpacing		=	(float)2.0 * PT;
	f->scale			=	(float)0.8;
	f->maxshrink	    =	(float)0.55;
	f->landscape	    =	0;
	f->titleleft	    =	0;
	f->stretchstaff	    =	1;
	f->stretchlast	    =	0;
	f->continueall	    =	0;
	f->breakall	    =	0;
	f->writehistory	    =	0;
	f->withxrefs	    =	0;
	f->oneperpage 	    =	0;
	f->PageNumTop       =   0;
	f->PageMirror       =   0;
	f->ShowTempo		=	1;
	f->ShowSource		=	1;
	f->ShowRhythm		=	1;
	f->ShowHistory		=	1;
	f->ShowTrans		=	1;
	f->CombineVoices	=	0;
	f->CarryAccs		=	0;
	f->HelperAccs		=	0;
	f->Watermark		=	0;
	f->WatermarkFile	=	0;
	f->WatermarkDate	=	0;
	f->NoInlineFmt		=	0;
	f->RollsClose		=	1;
	f->BreathsClose		=	1;
	f->FreeMetStyle		=	1;
	f->ManualPages		=	0;
	f->musiconly	    =	0;
	f->titlecaps	    =	0;
	f->barsperstaff	    =	0;
	f->lineskipfac	    =	(float)1.1;
	f->parskipfac 	    =	(float)0.1;
	f->StrTabSpace		=	(float)1.75;
	f->StaffTextHFac	=	(float)0.5;
	f->StaffTextVFac	=	(float)0.333;
	f->NoteTextFac		=	(float)0.5;
	f->WatermarkGray	=	(float)0.85;
	fontspec(&f->titlefont,     "Times-Roman",		18.0);
	fontspec(&f->subtitlefont,  "Times-Roman",		15.0);
	fontspec(&f->composerfont,  "Times-Italic",		12.0);
	fontspec(&f->partsfont,     "Times-Roman",		12.0);
	fontspec(&f->tempofont,     "Times-Bold",		10.0);
	fontspec(&f->vocalfont,     "Times-Bold",		14.0);
	fontspec(&f->textfont,      "Times-Roman",		10.0);
	fontspec(&f->wordsfont,     "Times-Roman",		10.0);
	fontspec(&f->gchordfont,    "Helvetica",		12.0);
	fontspec(&f->BookTitleFont, "Helvetica-Bold",	12.0);
	fontspec(&f->CopyrightFont, "Helvetica-Italic", 10.0);
	fontspec(&f->SourceFont,	"Helvetica-Italic", 10.0);
	fontspec(&f->StrTabFont,	"Times-Roman",		14.0);
	fontspec(&f->InfoFont,		"Helvetica",		11.0);
	fontspec(&f->HistoryFont,	"Helvetica",		10.0);
	for (i = 0; i < MAXVOICE; i++) {
		f->NoDecos[i] = FALSE;
		f->DecosBelow[i] = FALSE;
	}

	/* These objects can't be modified by the user. */
	fontspec(&f->DcDsFont,		"Times-Bold",		12.0);
	fontspec(&f->DynFont,		"Times-BoldItalic", 11.0);

	/* These objects should only be modifed using %% switches in the source. */
	f->InlineSyntax[0] = f->Syntax[0] = '\0';
}

/* ----- set_pretty2_format ----- */
void set_pretty2_format(struct FORMAT *f) {
	int i;

	strcpy (f->name, "pretty2");
	if (vb>=10) printf("Loading format \"%s\"\n",f->name);
	f->BookTitle[0] = '\0';
	f->BookCR[0] = '\0';
	f->pageheight 	    =	PAGEHEIGHT * IN;
	f->staffwidth 	    =	STAFFWIDTH * IN;
	f->leftmargin 	    =	LEFTMARGIN * IN;
	f->MirrorIndent		=	MIRRORINDENT * IN;
	f->topmargin	    =	(float)1.0  * CM;
	f->botmargin	    =	(float)1.0  * CM;
	f->topspace	    =	(float)0.8  * CM;
	f->titlespace 	    =	(float)0.4  * CM;
	f->subtitlespace    =	(float)0.1  * CM;
	f->composerspace    =	(float)0.3  * CM;
	f->musicspace 	    =	(float)0.25 * CM;
	f->partsspace 	    =	(float)0.2  * CM;
	f->staffsep	    =  (float)55.0  * PT;
	f->vocalspace 	    =  (float)23.0  * PT;
	f->textspace	    =	(float)0.2  * CM;
	f->wordsspace 	    =	(float)0.0  * CM;
	f->LineSep			=	(float)8.0 * PT;
	f->DecoSpacing		=	(float)2.0 * PT;
	f->scale	    =	(float)0.70;
	f->maxshrink	    =	(float)0.55;
	f->landscape	    =	0;
	f->titleleft	    =	1;
	f->stretchstaff	    =	1;
	f->stretchlast	    =	0;
	f->continueall	    =	0;
	f->breakall	    =	0;
	f->writehistory	    =	0;
	f->withxrefs	    =	0;
	f->oneperpage 	    =	0;
	f->PageNumTop       =   0;
	f->PageMirror       =   0;
	f->ShowTempo		=	1;
	f->ShowSource		=	1;
	f->ShowRhythm		=	1;
	f->ShowHistory		=	1;
	f->ShowTrans		=	1;
	f->CombineVoices	=	0;
	f->CarryAccs		=	0;
	f->HelperAccs		=	0;
	f->Watermark		=	0;
	f->WatermarkFile	=	0;
	f->WatermarkDate	=	0;
	f->NoInlineFmt		=	0;
	f->RollsClose		=	1;
	f->BreathsClose		=	1;
	f->ManualPages		=	0;
	f->FreeMetStyle		=	1;
	f->musiconly	    =	0;
	f->titlecaps	    =	0;
	f->barsperstaff	    =	0;
	f->lineskipfac	    =	(float)1.1;
	f->parskipfac 	    =	(float)0.1;
	f->StrTabSpace		=	(float)1.75;
	f->StaffTextHFac	=	(float)0.5;
	f->StaffTextVFac	=	(float)0.333;
	f->NoteTextFac		=	(float)0.5;
	f->WatermarkGray	=	(float)0.85;
	fontspec(&f->titlefont,     "Helvetica-Bold",	16.0);
	fontspec(&f->subtitlefont,  "Helvetica-Bold",	13.0);
	fontspec(&f->composerfont,  "Helvetica",		10.0);
	fontspec(&f->partsfont,     "Times-Roman",		12.0);
	fontspec(&f->tempofont,     "Times-Bold",		10.0);
	fontspec(&f->vocalfont,     "Times-Bold",		13.0);
	fontspec(&f->textfont,      "Times-Roman",		10.0);
	fontspec(&f->wordsfont,     "Times-Roman",		10.0);
	fontspec(&f->gchordfont,    "Helvetica",		12.0);
	fontspec(&f->BookTitleFont, "Helvetica-Bold",	12.0);
	fontspec(&f->CopyrightFont, "Helvetica-Italic", 10.0);
	fontspec(&f->StrTabFont,	"Times-Roman",		14.0);
	fontspec(&f->SourceFont,	"Helvetica-Italic", 10.0);
	fontspec(&f->InfoFont,		"Helvetica",		11.0);
	fontspec(&f->HistoryFont,	"Helvetica",		10.0);
	for (i = 0; i < MAXVOICE; i++) {
		f->NoDecos[i] = FALSE;
		f->DecosBelow[i] = FALSE;
	}

	/* These objects can't be modified by the user. */
	fontspec(&f->DcDsFont,		"Times-Bold",		12.0);
	fontspec(&f->DynFont,		"Times-BoldItalic", 11.0);

	/* These objects should only be modifed using %% switches in the source. */
	f->InlineSyntax[0] = f->Syntax[0] = '\0';
}

/* ----- print_format ----- */
void print_format(struct FORMAT f) {
	char	yn[2][5]={"no","yes"};
	char	descr[2][64] = { "% move decorations under staff", "% ignore decorations" };
	int		i;
	char	Units[4];
	float	UnitFac;

	if (ParamUnits == 1) {
		strcpy(Units, "cm");
		UnitFac = CM;
	} else if (ParamUnits == 2) {
		strcpy(Units, "pt");
		UnitFac = (float)1.0;
	} else {
		strcpy(Units, "in");
		UnitFac = IN;
	}


	printf("\nFormat \"%s\":\n", f.name);
	printf("  pageheight    %.2f%s\n", f.pageheight/UnitFac, Units);
	printf("  staffwidth    %.2f%s\n", f.staffwidth/UnitFac, Units);
	printf("  topmargin     %.2f%s\n", f.topmargin/UnitFac, Units);
	printf("  botmargin     %.2f%s\n", f.botmargin/UnitFac, Units);
	printf("  leftmargin    %.2f%s\n", f.leftmargin/UnitFac, Units);
	printf("  MirrorIndent  %.2f%s%c%s\n", f.MirrorIndent/UnitFac, Units, 9, "% how far to shift margin for left/right pages");
	printf("  topspace      %.2f%s\n", f.topspace/UnitFac, Units);
	printf("  titlespace    %.2f%s\n", f.titlespace/UnitFac, Units);
	printf("  subtitlespace %.2f%s\n", f.subtitlespace/UnitFac, Units);
	printf("  composerspace %.2f%s\n", f.composerspace/UnitFac, Units);
	printf("  musicspace    %.2f%s\n", f.musicspace/UnitFac, Units);
	printf("  partsspace    %.2f%s\n", f.partsspace/UnitFac, Units);
	printf("  wordsspace    %.2f%s\n", f.wordsspace/UnitFac, Units);
	printf("  textspace     %.2f%s\n", f.textspace/UnitFac, Units);
	printf("  vocalspace    %.2f%s\n", f.vocalspace/UnitFac, Units);
	printf("  staffsep      %.2f%s%c%s\n", f.staffsep/UnitFac, Units, 9, "% minimum space between staffs of one line");
	printf("  LineSep       %.2f%s%c%s\n", f.LineSep/UnitFac, Units, 9, "% space between complete lines of music");
	printf("  DecoSpacing   %.2f%s%c%s\n", f.DecoSpacing/UnitFac, Units, 9, "% vertical spacing between decorations");
	printf("  StrTabSpace   %.2f%s\n", f.StrTabSpace/UnitFac, Units);
	printf("  scale         %.2f\n",   f.scale);
	printf("  maxshrink     %.2f\n",   f.maxshrink);
	printf("  titlefont     %s %.1f\n", f.titlefont.name,f.titlefont.size);
	printf("  subtitlefont  %s %.1f\n", f.subtitlefont.name,f.subtitlefont.size);
	printf("  composerfont  %s %.1f\n", f.composerfont.name,f.composerfont.size);
	printf("  partsfont     %s %.1f\n", f.partsfont.name,f.partsfont.size);
	printf("  tempofont     %s %.1f\n", f.tempofont.name,f.tempofont.size);
	printf("  vocalfont     %s %.1f\n", f.vocalfont.name,f.vocalfont.size);
	printf("  gchordfont    %s %.1f\n", f.gchordfont.name,f.gchordfont.size);
	printf("  textfont      %s %.1f\n", f.textfont.name,f.textfont.size);
	printf("  wordsfont     %s %.1f\n", f.wordsfont.name,f.wordsfont.size);
	printf("  BookTitleFont %s %.1f\n", f.BookTitleFont.name,f.BookTitleFont.size);
	printf("  CopyrightFont %s %.1f\n", f.CopyrightFont.name,f.CopyrightFont.size);
	printf("  SourceFont    %s %.1f\n", f.SourceFont.name,f.SourceFont.size);
	printf("  StrTabFont    %s %.1f\n", f.StrTabFont.name,f.StrTabFont.size);
	printf("  InfoFont      %s %.1f\n", f.InfoFont.name,f.InfoFont.size);
	printf("  HistoryFont   %s %.1f\n", f.HistoryFont.name,f.HistoryFont.size);
	printf("  BookTitle     %s\n", f.BookTitle);
	printf("  Copyright     %s\n", f.BookCR);
	printf("  lineskipfac   %.1f%c%s\n", f.lineskipfac, 9, "% line skip multiplier for text font size");
	printf("  parskipfac    %.1f%c%s\n", f.parskipfac, 9, "% paragraph skip multiplier for text font size");
	printf("  StaffTextHFac %.1f%c%s\n", f.StaffTextHFac, 9, "% factor for \"<>^_\" text shifting above/below staff");
	printf("  StaffTextVFac %.1f%c%s\n", f.StaffTextVFac, 9, "% factor for \"<>^_\" text shifting above/below staff");
	printf("  NoteTextFac   %.1f%c%s\n", f.NoteTextFac, 9, "% factor for \"<>^_\" text shifting near notehead");
	printf("  WatermarkGray %.2f%c%s\n", f.WatermarkGray, 9, "% gray level for watermarks (0.0 (black) to 1.0 (white))");
	printf("  barsperstaff  %d\n",	f.barsperstaff);
	printf("  landscape     %s%c%s\n", yn[f.landscape], 9, "% turn the page sideways");
	printf("  titleleft     %s\n", yn[f.titleleft]);
	printf("  titlecaps     %s\n", yn[f.titlecaps]);
	printf("  musiconly     %s%c%s\n", yn[f.musiconly], 9, "% turn off lyrics");
	printf("  stretchstaff  %s\n", yn[f.stretchstaff]);
	printf("  stretchlast   %s\n", yn[f.stretchlast]);
	printf("  writehistory  %s%c%s\n", yn[f.writehistory], 9, "% print some info fields");
	printf("  continueall   %s\n", yn[f.continueall]);
	printf("  breakall      %s\n", yn[f.breakall]);
	printf("  oneperpage    %s%c%s\n", yn[f.oneperpage], 9, "% insert page break after every tune");
	printf("  PageMirror    %s%c%s\n", yn[f.PageMirror], 9, "% make left and right pages");
	printf("  PageNumTop    %s%c%s\n", yn[f.PageNumTop], 9, "% move page numbers to top");
	printf("  ShowTempo     %s%c%s\n", yn[f.ShowTempo], 9, "% print tempo");
	printf("  ShowSource    %s%c%s\n", yn[f.ShowSource], 9, "% print source field");
	printf("  ShowRhythm    %s%c%s\n", yn[f.ShowRhythm], 9, "% print rhythm field (when writehistory = yes)");
	printf("  ShowHistory   %s%c%s\n", yn[f.ShowHistory], 9, "% print history field (when writehistory = yes)");
	printf("  ShowTrans     %s%c%s\n", yn[f.ShowTrans], 9, "% print transcription notes (when writehistory = yes)");
	printf("  CombineVoices %s%c%s\n", yn[f.CombineVoices], 9, "% combine all voices on a staff");
	printf("  CarryAccs     %s%c%s\n", yn[f.CarryAccs], 9, "% carry accidentals through measure (modern style)");
	printf("  HelperAccs    %s%c%s\n", yn[f.HelperAccs], 9, "% use helper accidentals (span is 1 measure)");
	printf("  Watermark     %s%c%s\n", yn[f.Watermark], 9, "% use copyright string (above) as a watermark");
	printf("  WatermarkDate %s%c%s\n", yn[f.WatermarkDate], 9, "% append current date to watermark watermark");
	printf("  WatermarkFile %s%c%s\n", yn[f.WatermarkFile], 9, "% append filename to watermark as a watermark");
	printf("  NoInlineFmt   %s%c%s\n", yn[f.NoInlineFmt], 9, "% ignore %%commands");
	printf("  RollsClose    %s%c%s\n", yn[f.RollsClose], 9, "% move roll marks close to noteheads");
	printf("  BreathsClose  %s%c%s\n", yn[f.BreathsClose], 9, "% move breath marks close to notes");
	printf("  ManualPages   %s%c%s\n", yn[f.ManualPages], 9, "% fill partial pages (use %%newpage to force break)");
	printf("  FreeMetStyle  %d%c%s\n", f.FreeMetStyle, 9, "% 0 = none, 1 = free, 2 = free/meter, 3 = fm, 4 = nothing");
	printf("  withxrefs     %s%c%s\n", yn[f.withxrefs], 9, "% print xref number with title");
	printf("%% These parameters are for individual voices (1-%d)\n", MAXVOICE);
	for (i = 0; i < MAXVOICE; i++) {
		printf("  NoDecos       %2d %s%c%s\n", i + 1, yn[f.NoDecos[i]], 9, descr[1]);
		printf("  DecosBelowSt  %2d %s%c%s\n", i + 1, yn[f.DecosBelow[i]], 9, descr[0]);
		descr[0][0] = descr[1][0] = '\0';
	}
}

/* ----- g_unum: read a number with a unit ----- */
void g_unum(char *l,
	    int  nch,
	    float *num)
{
	float a,b;
	char unit[81];

	strcpy(unit,"pt");
	sscanf(l+nch,"%f%s", &a, unit);

	if	(!strcmp(unit,"cm")) b=a*CM;
	else if (!strcmp(unit,"in")) b=a*IN;
	else if (!strcmp(unit,"pt")) b=a*PT;
	else {
		printf("++++ Unknown unit \"%s\" in line: %s\n",unit,l);
		exit(3);
	}
	*num = b;
}

/* ----- g_logv: read a logical variable----- */
static void g_logv(char *l, int  nch, int  *v) {
	int k;
	char t[31];

	strcpy(t,"1");
	sscanf (l+nch,"%s", t);
	if (!strcmp(t,"1") || !strcmp(t,"yes") || !strcmp(t,"true"))
		k=1;
	else if (!strcmp(t,"0") || !strcmp(t,"no") || !strcmp(t,"false"))
		k=0;
	else {
		printf("++++ Unknown logical \"%s\" in line: %s\n",t,l);
		exit(3);
	}
	*v = k;
}

/* ----- g_fltv: read a float variable, no units----- */
static void g_fltv(char   *l, int    nch, float  *v) {
	sscanf(l+nch,"%f", v);
}

/* ----- g_intv: read an int variable, no units ----- */
static void g_intv(char *l, int nch, int *v) {
	sscanf (l+nch,"%d", v);
}

/* ----- g_intv: read a string containing spaces ----- */
static void g_strv(char *l, int nch, char *v) {
	l += nch;
	while (*l && isspace(*l)) l++;
	strcpy(v, l);
}

/* ----- g_fspc: read a font specifier ----- */
static void g_fspc(char *l, int  nch, struct FONTSPEC *fn) {
	char	fname[101];
	float	fsize;

	fsize=fn->size;
	sscanf(l+nch,"%s %f", fname, &fsize);
	if (strcmp(fname,"*"))
		strcpy(fn->name, fname);
	fn->size = fsize;

	if (!file_initialized) add_font (fn);
}

/* ----- g_IdxLog: read an index and a logical value ----- */
static void g_IdxLog(char *l, int nch, int *Idx, int *v, int MaxIdx) {
	char	buff[256];

	sscanf(l + nch, "%d %s", Idx, buff);
	if (*Idx < 1) *Idx = 1;
	if (*Idx > MaxIdx) *Idx = MaxIdx;
	if (stricmp(buff, "yes")) {
		*v = FALSE;
	} else {
		*v = TRUE;
	}
}

/* ----- interpret_format_line ----- */
/* read a line with a format directive, set in format struct f */
int interpret_format_line(char l[], struct FORMAT *f) {
	char	w[81],fnm[81];
	int		nch,i,fnum, logv;
	struct	FONTSPEC tempfont;

	w[0] = '\0';
	sscanf(l,"%s%n", w, &nch);
	if (w[0] == '\0') return 0;
	if (w[0]=='%') return 0;
	if (vb>=6) printf("Interpret format line: %s\n", l);
	if (!stricmp(w,"end")) return 1;

	if	(!stricmp(w,"pageheight"))    g_unum(l,nch,&f->pageheight);
	else if (!stricmp(w,"staffwidth"))    g_unum(l,nch,&f->staffwidth);
	else if (!stricmp(w,"topmargin"))     g_unum(l,nch,&f->topmargin);
	else if (!stricmp(w,"botmargin"))     g_unum(l,nch,&f->botmargin);
	else if (!stricmp(w,"leftmargin"))    g_unum(l,nch,&f->leftmargin);
	else if (!stricmp(w, "MirrorIndent")) g_unum(l,nch,&f->MirrorIndent);
	else if (!stricmp(w,"topspace"))      g_unum(l,nch,&f->topspace);
	else if (!stricmp(w,"wordsspace"))	  g_unum(l,nch,&f->wordsspace);
	else if (!stricmp(w,"titlespace"))    g_unum(l,nch,&f->titlespace);
	else if (!stricmp(w,"subtitlespace")) g_unum(l,nch,&f->subtitlespace);
	else if (!stricmp(w,"composerspace")) g_unum(l,nch,&f->composerspace);
	else if (!stricmp(w,"musicspace"))    g_unum(l,nch,&f->musicspace);
	else if (!stricmp(w,"partsspace"))    g_unum(l,nch,&f->partsspace);
	else if (!stricmp(w,"staffsep"))      g_unum(l,nch,&f->staffsep);
	else if (!stricmp(w,"LineSep"))       g_unum(l,nch,&f->LineSep);
	else if (!stricmp(w,"DecoSpacing"))   g_unum(l,nch,&f->DecoSpacing);
	else if (!stricmp(w,"vocalspace"))    g_unum(l,nch,&f->vocalspace);
	else if (!stricmp(w,"textspace"))     g_unum(l,nch,&f->textspace);
	else if (!stricmp(w,"StrTabSpace"))   g_unum(l,nch,&f->StrTabSpace);

	else if (!stricmp(w,"scale"))	      g_fltv(l,nch,&f->scale);
	else if (!stricmp(w,"maxshrink"))     g_fltv(l,nch,&f->maxshrink);
	else if (!stricmp(w,"lineskipfac"))   g_fltv(l,nch,&f->lineskipfac);
	else if (!stricmp(w,"parskipfac"))    g_fltv(l,nch,&f->parskipfac);
	else if (!stricmp(w,"parskipfac"))    g_fltv(l,nch,&f->parskipfac);
	else if (!stricmp(w,"StaffTextHFac")) g_fltv(l,nch,&f->StaffTextHFac);
	else if (!stricmp(w,"StaffTextVFac")) g_fltv(l,nch,&f->StaffTextVFac);
	else if (!stricmp(w,"NoteTextFac"))   g_fltv(l,nch,&f->NoteTextFac);
	else if (!stricmp(w,"WatermarkGray")) g_fltv(l,nch,&f->WatermarkGray);
	else if (!stricmp(w,"barsperstaff"))  g_intv(l,nch,&f->barsperstaff);

	else if (!stricmp(w,"titleleft"))     g_logv(l,nch,&f->titleleft);
	else if (!stricmp(w,"titlecaps"))     g_logv(l,nch,&f->titlecaps);
	else if (!stricmp(w,"landscape"))     g_logv(l,nch,&f->landscape);
	else if (!stricmp(w,"musiconly"))     g_logv(l,nch,&f->musiconly);
	else if (!stricmp(w,"stretchstaff"))  g_logv(l,nch,&f->stretchstaff);
	else if (!stricmp(w,"stretchlast"))   g_logv(l,nch,&f->stretchlast);
	else if (!stricmp(w,"continueall"))   g_logv(l,nch,&f->continueall);
	else if (!stricmp(w,"breakall"))      g_logv(l,nch,&f->breakall);
	else if (!stricmp(w,"writehistory"))  g_logv(l,nch,&f->writehistory);
	else if (!stricmp(w,"withxrefs") )    g_logv(l,nch,&f->withxrefs);
	else if (!stricmp(w,"oneperpage") )   g_logv(l,nch,&f->oneperpage);
	else if (!stricmp(w,"PageMirror"))	  g_logv(l,nch,&f->PageMirror);
	else if (!stricmp(w,"PageNumTop"))	  g_logv(l,nch,&f->PageNumTop);
	else if (!stricmp(w,"ShowTempo"))	  g_logv(l,nch,&f->ShowTempo);
	else if (!stricmp(w,"ShowSource"))	  g_logv(l,nch,&f->ShowSource);
	else if (!stricmp(w,"ShowRhythm"))	  g_logv(l,nch,&f->ShowRhythm);
	else if (!stricmp(w,"ShowHistory"))	  g_logv(l,nch,&f->ShowHistory);
	else if (!stricmp(w,"ShowTrans"))	  g_logv(l,nch,&f->ShowTrans);
	else if (!stricmp(w,"CombineVoices")) g_logv(l,nch,&f->CombineVoices);
	else if (!stricmp(w,"CarryAccs"))     g_logv(l,nch,&f->CarryAccs);
	else if (!stricmp(w,"HelperAccs"))    g_logv(l,nch,&f->HelperAccs);
	else if (!stricmp(w,"Watermark"))     g_logv(l,nch,&f->Watermark);
	else if (!stricmp(w,"WatermarkDate")) g_logv(l,nch,&f->WatermarkDate);
	else if (!stricmp(w,"WatermarkFile")) g_logv(l,nch,&f->WatermarkFile);
	else if (!stricmp(w,"NoInlineFmt"))   g_logv(l,nch,&f->NoInlineFmt);
	else if (!stricmp(w,"RollsClose"))    g_logv(l,nch,&f->RollsClose);
	else if (!stricmp(w,"BreathsClose"))  g_logv(l,nch,&f->BreathsClose);
	else if (!stricmp(w,"ManualPages"))   g_logv(l,nch,&f->ManualPages);
	else if (!stricmp(w,"FreeMetStyle"))  g_intv(l,nch,&f->FreeMetStyle);
	else if (!stricmp(w,"titlefont"))     g_fspc(l,nch,&f->titlefont);
	else if (!stricmp(w,"subtitlefont"))  g_fspc(l,nch,&f->subtitlefont);
	else if (!stricmp(w,"vocalfont"))     g_fspc(l,nch,&f->vocalfont);
	else if (!stricmp(w,"partsfont"))     g_fspc(l,nch,&f->partsfont);
	else if (!stricmp(w,"tempofont"))     g_fspc(l,nch,&f->tempofont);
	else if (!stricmp(w,"textfont"))      g_fspc(l,nch,&f->textfont);
	else if (!stricmp(w,"composerfont"))  g_fspc(l,nch,&f->composerfont);
	else if (!stricmp(w,"wordsfont"))     g_fspc(l,nch,&f->wordsfont);
	else if (!stricmp(w,"gchordfont"))    g_fspc(l,nch,&f->gchordfont);
	else if (!stricmp(w,"BookTitleFont")) g_fspc(l,nch,&f->BookTitleFont);
	else if (!stricmp(w,"CopyrightFont")) g_fspc(l,nch,&f->CopyrightFont);
	else if (!stricmp(w,"SourceFont"))    g_fspc(l,nch,&f->SourceFont);
	else if (!stricmp(w,"StrTabFont"))    g_fspc(l,nch,&f->StrTabFont);
	else if (!stricmp(w,"InfoFont"))      g_fspc(l,nch,&f->InfoFont);
	else if (!stricmp(w,"HistoryFont"))   g_fspc(l,nch,&f->HistoryFont);
	else if (!stricmp(w,"BookTitle"))	  g_strv(l,nch,f->BookTitle);
	else if (!stricmp(w,"Copyright"))	  g_strv(l,nch,f->BookCR);
	else if (!stricmp(w,"InlineSyntax"))  g_strv(l,nch,f->InlineSyntax);
	else if (!stricmp(w,"Syntax"))		  g_strv(l,nch,f->Syntax);
	else if (!stricmp(w,"NoDecos")) {
		g_IdxLog(l, nch, &i, &logv, MAXVOICE);
		f->NoDecos[i - 1] = logv;
	} else if (!stricmp(w, "DecosBelowSt")) {
		g_IdxLog(l, nch, &i, &logv, MAXVOICE);
		f->DecosBelow[i - 1] = logv;
	} else if (!stricmp(w,"font")) {
		sscanf(l,"%*s %s", fnm);
		fnum=-1;
		for (i=0;i<nfontnames;i++) {
			if (!stricmp(fnm,fontnames[i]))
				fnum=i;
		}
		if (fnum<0) {
			if (file_initialized) {
				printf("++++ Cannot predefine when output file open: %s\n", l);
				exit (3);
			}
			tempfont.size=12.0;
			g_fspc(l,nch,&tempfont);
		}
	} else {
		if (vb>=5) printf("Ignore format line: %s\n", l);
		/* [JSA] 3-5-00 -- deleted the following return because
		   we don't want to stop reading the file because of 1 bad param. */
		/*return 0;*/ 
	}
	return 0;
}

/* ----- read_fmt_file ----- */
int read_fmt_file(char filename[],
		  char dirname[],
		  struct FORMAT *f)
{
	FILE *fp;
	char line[BSIZE],fname[201];
	int i,end;

	strcpy(fname,filename);
	if ((fp = fopen(fname,"r")) == NULL) {
		if (dirname[0] == '\0')
			return 0;
		sprintf("%s/%s", dirname, filename);
		if ((fp = fopen(fname,"r")) == NULL)
			return 0;
	}

	if (vb>=4)
		printf ("Reading format file %s:\n", fname);
	printf("%s .. ", fname);
	for (i=0;i<200;i++) {
		line[0] = '\0';
		if (!fgets(line, BSIZE, fp)) break;
		line[strlen(line)-1]='\0';		// Remove newline character
		end=interpret_format_line(line,f);
		if (end || feof(fp)) break;
	}
	fclose(fp);
	return 1;
}
