[net.sources.games] moriachr - format Moria character for TeX

colonel@ellie.UUCP (04/16/86)

This is a VMS "C" program that prints a nice-looking MORIA character
sheet.
-----MORIACHR.CLD-----------------------------------------------------
DEFINE VERB MORIACHR
IMAGE "DUA1:[CSD0.CSDSICHE]MORIACHR.EXE"	... or wherever you put it.
        PARAMETER P1, PROMPT="File", VALUE(REQUIRED,TYPE=$FILE)
-----MORIACHR.C-------------------------------------------------------
/*
 *      moriachr - reformat moria character dump for TeX.
 *      the Colonel.  1986.
 *      A real hack ... should have been written in FORTRAN.
 *	send flames to csdsicher@sunyabva.bitnet.
 */
/*
 *	$ MORIACHR file.ext
 *
 *	Default extension is .CHR
 *	Writes to file.TEX
 */
#include <ctype.h>
#include <errno.h>
#include <stat.h>
#include <stdio.h>
#include <time.h>

#define GETLINE {for (bp=buf; '\n'!=(*bp=getc(In)); bp++);}
#define SKIPLINE {while('\n'!=getc(In));}
char buf[80];
FILE *In, *Out;

char *miscabil[9] = {
	"Fighting","Throw/Bows","Saving Throw",
	"Stealth","Disarming","Magic Device",
	"Perception","Searching","Infra-Vision"};
char *misc[9] = {
	"fighting","throwbows","savingthrow",
	"stealth","disarming","magicdevice",
	"perception","searching","infravision"};
char *xstat[6]  = {
	"Strength","Intelligence","Wisdom",
	"Dexterity","Constitution","Charisma"};
char *cstat[3] = {
	"Level","Experience","Gold"};
char *font[] = {
	"smalltype=amr9","smaller=amr8","bo=amb10",
	"bigbold=ambx10 scaled \\magstep1",
	"bigmit=ammi10 scaled \\magstep2",
	"csc=amcsc10",""}
, **fpp;

plussify()
{
	int i;
	for (i=20; i>=15; i--)
		if (buf[i]==' ') {
			buf[i]='+';
			return;
		}
		else if (buf[i]=='-') return;
}

char *
minussify(s)
char *s;
{
	int eqmode, ismath, paren;
	paren = 1;
	eqmode = 0;
	for ( ; *s!='\n'; s++) {
		ismath = (int)strchr("0123456789,+-",*s);
		if (*s=='(' || *s=='[') paren+=1;
		else if (*s==')' || *s==']') paren-=1;
		if (eqmode && !ismath) {
			eqmode=0;
			fprintf(Out,"}$%c",*s);
		}
		else if (!eqmode && paren && ismath) {
			eqmode = 1;
			fprintf(Out,"$");
			fprintf(Out,"{\\mit");
			putc(*s,Out);
		}
		else putc(*s,Out);
	}
}

pritems(n)
int n;
{
	int i;
	fprintf(Out,"\\setbox40=\\vtop{\\baselineskip=10pt\n");
	for (i=0; i<(n>5? (n+1)/2: n); i++)
		fprintf(Out,"  \\hbox{\\smaller\\item%c}\n",'a'+i);
	fprintf(Out,"}\n");
	if (n>5) {
		fprintf(Out,"\\setbox41=\\vtop{\\baselineskip=10pt\n");
		for (i=(n+1)/2; i<n; i++)
			fprintf(Out,"  \\hbox{\\smaller\\item%c}\n",'a'+i);
		fprintf(Out,"}\n");
	}
	fprintf(Out,"  \\vskip 1.5em\n");
	fprintf(Out,"  \\centerline{\\csc Inventory}\n");
	fprintf(Out,"  \\vskip 10pt\n");
	fprintf(Out,"\\centerline{%s}\n", n>5?"\\box40\\quad\\box41":
	"\\box40");
}

prstat(s)
char *s;
{
	int slashf, i;
	slashf=0;
	fprintf(Out,"\\def\\%s{\\mit",s);
	for (i=72; i<78; i++) {
		if (isdigit(buf[i])) putc(buf[i],Out);
		else if ('/'==buf[i]) {
			fprintf(Out,"\\rlap{{\\rm /}");
			slashf++;
		}
	}
	if (slashf) fprintf(Out,"}");
	fprintf(Out,"}\n");
}

char *
trunc(s)
char *s;
{
	int i;
	static char v[100];
	strcpy(v,s);
	for (i=strlen(v)-1; i>0; i--)
		if (v[i]!=' ') {
			v[i+1]='\0';
			return v;
		}
	v[1]='\0';
	return v;
}

sub(s,m1,m2,all)
char *s, *m1, *m2;
int all;
{
	for ( ; '\n'!= *s; s++)
		if (!strncmp(s,m1,strlen(m1))) {
			strncpy(s,m2,strlen(m2));
			if (!all) return;
		}
}

char *monthname[]={
	"January","February","March","April",
	"May","June","July","August","September","October",
	"November","December"};

char *
cdate(t)
unsigned t;     /* UNIX-style timestamp */
{
	static char chold[20];
	struct tm *thold;
	thold = localtime(&t);
	sprintf(chold,"%s %d, %d",monthname[thold->tm_mon],
	thold->tm_mday, thold->tm_year+1900);
	return chold;
}

main(argc,argv)
int argc;
char **argv;
{
	int i, female, madesub, nitems;
	char outname[80];
	char *bp, hold[21];
	struct stat statbuf;
	madesub = 0;
	if (strchr(argv[1],'.')) {
		if (stat(argv[1],&statbuf)
		    || NULL == (In = fopen(argv[1],"r"))) {
			fprintf(stderr,"MORIACHR-E-CANTREAD, Cannot read %s\n",argv[1]);
			exit(0);
		}
	}
	else {
		strcpy(buf,argv[1]);
		strcat(buf,".chr");
		if (stat(buf,&statbuf) ||
		    NULL == (In = fopen(buf,"r"))) {
			if (stat(argv[1],&statbuf) ||
			    NULL==(In = fopen(argv[1],"r"))) {
				fprintf(stderr,"MORIACHR-E-CANTREAD, Cannot read %s\n",buf);
				exit(0);
			}
		}
	}
	strcpy(outname,argv[1]);
	if (bp=strchr(outname,'.')) *bp = '\0';
	strcat(outname,".tex");
	Out = fopen(outname,"w","rfm=var","mrs=80","rat=cr");
	for (fpp=font; **fpp; fpp++)
		fprintf(Out,"\\font\\%s\n",*fpp);
	fprintf(Out,"\\nopagenumbers\n");
	fprintf(Out,"\\def\\rogue{$\\}\\!\\!\\bullet\\!\\!\\{$}\n");
	fprintf(Out,"\\def\\star{{\\bigmit?}}\n");
	fprintf(Out,"\\def\\statwidth{1.3in}\n");
	fprintf(Out,"\\def\\abilwidth{1.7in}\n");
	fprintf(Out,"\\hsize=6in\n");
	fprintf(Out,"\\def\\cdate{%s}\n",cdate(statbuf.st_ctime));
	for (i=0; i<4; i++) SKIPLINE;
	GETLINE;
	buf[29]='\0';
	fprintf(Out,"\\def\\nw{{%s}} %% without space\n",trunc(buf+9));
	fprintf(Out,"\\def\\nm{%s } %% with space\n",trunc(buf+9));
/*
 *      This little kludge is for when the background starts with "Your".
 */
	fprintf(Out,"\\def\\nmr{%s's }\n",trunc(buf+9));
	buf[53]='\0';
	fprintf(Out,"\\def\\age{%s}\n",trunc(buf+49));
	prstat("Str");
	GETLINE;
	fprintf(Out,"\\def\\race{%-20.20s}\n",buf+9);
	fprintf(Out,"\\def\\height{%-4.4s}\n",buf+49);
	prstat("Int");
	GETLINE;
	fprintf(Out,"\\def\\sex{%-20.20s}\n",buf+9);
	female = 'F' == buf[9];
	fprintf(Out,"\\def\\weight{%-4.4s}\n",buf+49);
	prstat("Wis");
	GETLINE;
	fprintf(Out,"\\def\\class{%-20.20s}\n",buf+9);
	switch(buf[10]-buf[9]) {
	case 'a'-'W':
		bp = "$\\spadesuit$"; 
		break;
	case 'a'-'R':
		bp = "\\star"; 
		break;
	case 'a'-'P':
		bp = "$\\oplus$"; 
		break;
	case 'a'-'M':
		bp = "$\\infty$"; 
		break;
	case 'r'-'P':
		bp = "$\\Delta$"; 
		break;
	case 'o'-'R':
		bp = "\\rogue"; 
		break;
	default:
		bp = "\\bullet";
	}
	fprintf(Out,"\\def\\clsym{%s}\n",bp);
	fprintf(Out,"\\def\\socialclass{%-4.4s}\n",buf+49);
	prstat("Dex");
	GETLINE;
	fprintf(Out,"\\def\\title{%-20.20s}\n",buf+9);
	prstat("Con");
	GETLINE;
	prstat("Cha");
	for (i=0; i<4; i++) SKIPLINE;
	GETLINE;
	plussify();
	fprintf(Out,"\\def\\tohit{%-6.6s}\n",buf+15);
	fprintf(Out,"\\def\\Lev{%-6.6s}\n",buf+38);
	fprintf(Out,"\\def\\maxhitpts{%-6.6s}\n",buf+65);
	GETLINE;
	plussify();
	fprintf(Out,"\\def\\todam{%-6.6s}\n",buf+15);
	fprintf(Out,"\\def\\Exp{%-6.6s}\n",buf+38);
	fprintf(Out,"\\def\\curhitpts{%-6.6s}\n",buf+65);
	GETLINE;
	plussify();
	fprintf(Out,"\\def\\toarmor{%-6.6s}\n",buf+15);
	fprintf(Out,"\\def\\Gol{%-6.6s}\n",buf+38);
	fprintf(Out,"\\def\\maxmana{%-6.6s}\n",buf+65);
	GETLINE;
	fprintf(Out,"\\def\\armorclass{%-6.6s}\n",buf+15);
	fprintf(Out,"\\def\\curmana{%-6.6s}\n",buf+65);
	for (i=0; i<4; i++) SKIPLINE;
	for (i=0; i<3; i+=1) {
		GETLINE;
		fprintf(Out,"\\def\\%s{%-10.10s}\n",misc[i],buf+16);
		fprintf(Out,"\\def\\%s{%-10.10s}\n",misc[i+3],buf+42);
		fprintf(Out,"\\def\\%s{%-10.10s}\n",misc[i+6],buf+68);
	}
	for (i=0; i<3; i++) SKIPLINE;
	fprintf(Out,"\\def\\background{\n");
	for (i=0; i<6; i++) {
		GETLINE;
		for (bp=buf; *bp; bp++) if (' '!=*bp) break;
		if ('\n'==*bp) continue;
		sub(buf,"have","has ",1);
		sub(buf,"are","is ",1);
		if (!madesub++) sub(buf,"You","\\nm",0);
		sub(buf,"You",female?"She":"He ",1);
		for (bp=buf+5; '\n'!=*bp; bp++) putc(*bp,Out);
		putc('\n',Out);
	}
	fprintf(Out,"}\n");
	/*
	 *      Equipment list.
	 */
	for (i=0; i<3; i++) SKIPLINE;
	fprintf(Out,"\\setbox30=\\vbox{\\baselineskip=11pt\n");
	for (;;) {
		GETLINE;
		for (bp=buf; *bp; bp++) if (' '!=*bp) break;
		if ('\f'==*bp) break;
		fprintf(Out,"\\hbox{\\smalltype\n");
		minussify(buf+2);
		fprintf(Out,"}\n");
	}
	fprintf(Out,"}\n");
	/*
	 *      Inventory.
	 */
	nitems = 0;
	for (i=0; i<5; i++) SKIPLINE;
	for (;;) {
		GETLINE;
		for (bp=buf; *bp; bp++) if (' '!=*bp) break;
		if ('\f'==*bp) break;
		fprintf(Out,"\\def\\item%c{",'a'+nitems);
		for (bp=buf; '\n'!=*bp; bp++) putc(*bp,Out);
		fprintf(Out,"}\n");
		nitems += 1;
	}
	/*
	 *      Print the data.
	 */
	fprintf(Out,"\\centerline{");
	fprintf(Out,"\\clsym\\qquad{\\bigbold\\nw}\\qquad\\clsym}\n");
	fprintf(Out,"\\vskip 5pt\n");
	fprintf(Out,"\\centerline{\\cdate}\n");
	fprintf(Out,"\\vskip 2em\n");
	fprintf(Out,"\\setbox0=\\vtop{\\halign{\\bf#\\hfil&\\quad#\\hfil\\cr\n");
	fprintf(Out,"  Name&\\nw\\cr\n");
	fprintf(Out,"  Race&\\race\\cr\n");
	fprintf(Out,"  Sex&\\sex\\cr\n");
	fprintf(Out,"  Class&\\class\\cr\n");
	fprintf(Out,"  Title&\\title\\cr\n");
	fprintf(Out,"}}\n");
	fprintf(Out,"\\def\\dotbox #1/#2.{\\hbox to \\statwidth");
	fprintf(Out,"{{\\bf #1}\\dotfill{\\oldstyle #2}}}\n");
	fprintf(Out,"\\setbox1=\\vtop{\n");
	fprintf(Out,"\\dotbox Age/\\age.\n");
	fprintf(Out,"\\dotbox Height/\\height.\n");
	fprintf(Out,"\\dotbox Weight/\\weight.\n");
	fprintf(Out,"\\dotbox Social Class/\\socialclass.\n");
	fprintf(Out,"}\n");
	fprintf(Out,"\\setbox2=\\vtop{");
	for (i=0; i<6; i++)
		fprintf(Out,"  \\dotbox %s/\\%3.3s.\n",xstat[i],xstat[i]);
	fprintf(Out,"}\n");
	fprintf(Out,"\\setbox3=");
	fprintf(Out,"\\vtop{\\halign{\\hfil$\\oldstyle#$&\\enspace\\bf#\\hfil\\cr\n");
	fprintf(Out,"  \\tohit&to Hit\\cr\n");
	fprintf(Out,"  \\todam&to Damage\\cr\n");
	fprintf(Out,"  \\toarmor&to Armor\\cr\n");
	fprintf(Out,"  \\armorclass&Total Armor\\cr\n");
	fprintf(Out,"}}\n");
	fprintf(Out,"\\setbox4=\\vtop{\n");
	for (i=0; i<3; i++)
		fprintf(Out,"\\dotbox %s/\\%3.3s.\n",cstat[i],cstat[i]);
	fprintf(Out,"}\n");
	fprintf(Out,"\\setbox5=\\vtop{\\halign{\\hfil$\\mit#$&\\enspace\\bf#\\hfil\\cr\n ");
	fprintf(Out,"  \\maxhitpts&Maximum H.P.\\cr\n");
	fprintf(Out,"  \\curhitpts&Current H.P.\\cr\n");
	fprintf(Out,"  \\maxmana&Maximum Mana\\cr\n");
	fprintf(Out,"  \\curmana&Current Mana\\cr\n");
	fprintf(Out,"}}\n");
	for (i=0; i<3; i++)
		abilbox(6+i,miscabil[3*i],misc[3*i],
		miscabil[3*i+1],misc[3*i+1],
		miscabil[3*i+2],misc[3*i+2]);
	fprintf(Out,"\\centerline{\\hbox{\\box0\\hskip 0.5in\\box1\\hskip 0.5in\\box2}}\n");
	fprintf(Out,"\\vskip 1.5em\n");
	fprintf(Out,"\\centerline{\\hbox{\\box3\\hskip 0.5in\\box4\\hskip 0.5in\\box5}}\n");
	fprintf(Out,"\\vskip 2em\n");
	fprintf(Out,"\\centerline{\\csc Miscellaneous Abilities}\n");
	fprintf(Out,"\\vskip 1em\n");
	fprintf(Out,"\\centerline{\\hbox{\\box6\\qquad\\box7\\qquad\\box8}}\n");
	fprintf(Out,"\\vskip 2em\n");
	fprintf(Out,"\\centerline{\\csc Character Background}\n");
	fprintf(Out,"\\vskip 5pt\n");
	fprintf(Out,"{\\narrower\\narrower\\smallskip\\background\\smallskip}\n");
	fprintf(Out,"\\vskip 1em\n");
	fprintf(Out,"\\setbox20=\\vbox{\n");
	fprintf(Out,"  \\halign{\\hfil\\smalltype#\\hfil\\cr\n");
	fprintf(Out,"  {\\csc Equipment}\\cr\n");
	fprintf(Out,"  \\noalign{\\vskip 1em}\n");
	fprintf(Out,"  \\hbox{\\box30}\\cr}\n}\n");
	fprintf(Out,"\\centerline{\\box20}\n");
	if (nitems) pritems(nitems);
	fprintf(Out,"\\bye\n");
	exit(1);
}

abilbox(n,a1,b1,a2,b2,a3,b3)
int n;
char *a1, *b1, *a2, *b2, *a3, *b3;
{
	char *format;
	fprintf(Out,"\\setbox%d=\\vtop{\n",n);
	format="\\hbox to\\abilwidth{\\bo %s\\dotfill\\%s}\n";
	fprintf(Out,format,a1,b1);
	fprintf(Out,format,a2,b2);
	fprintf(Out,format,a3,b3);
	fprintf(Out,"}\n");
}
-- 
Col. G. L. Sicherman
UU: ...{rocksvax|decvax}!sunybcs!colonel
CS: colonel@buffalo-cs
BI: csdsicher@sunyabva