Interdata_v6/usr/source/troff/eqn/src.a

Find at most related files.
including files from this version of Unix.

ee.g~\{#
#include "e.h"
#
int	fromflg	0;
\}
%term	CONTIG QTEXT  SPACE THIN TAB
%term	MATRIX LCOL CCOL RCOL COL
%term	MARK LINEUP
%term	SUM INT PROD UNION INTER
%term	LPILE PILE CPILE RPILE ABOVE
%term	DEFINE TDEFINE NDEFINE DELIM  GSIZE GFONT INCLUDE
%right	FROM TO
%left	OVER SQRT
%right	SUP SUB
%right	SIZE FONT ROMAN ITALIC BOLD FAT
%right	UP DOWN BACK FWD
%left	MQ MQ1
%left	LEFT RIGHT
%right	DOT DOTDOT HAT TILDE BAR UNDER VEC DYAD

%%

stuff	: eqn 	={ putout($1); }
	| error	={ error(!FATAL, "syntax error"); }
	|	={ eqnreg = 0; }
	;

eqn	: box
	| eqn box	={ eqnbox($1, $2, 0); }
	| eqn lineupbox	={ eqnbox($1, $2, 1); }
	| LINEUP	={ lineup(0, 0); }
	;

lineupbox : LINEUP box	={ $$ = $2; }
	;

matrix	: MATRIX	={ $$ = ct; } ;

collist	: column
	| collist column
	;

column	: lcol MQ list MQ1	={ column('L',$1,$3); }
	| ccol MQ list MQ1	={ column('C',$1,$3); }
	| rcol MQ list MQ1	={ column('R',$1,$3); }
	| col MQ list MQ1	={ column('-',$1,$3); }
	;

lcol	: LCOL		={ $$ = ct++; } ;
ccol	: CCOL		={ $$ = ct++; } ;
rcol	: RCOL		={ $$ = ct++; } ;
col	: COL		={ $$ = ct++; } ;

sbox	: sup box	%prec SUP	={ $$ = $2; }
	;

tbox	: to box	%prec TO	={ $$ = $2; }
	|		%prec FROM	={ $$ = 0; }
	;

box	: box OVER box	={ boverb($1,$3); }
	| MARK box	={ mark($2); }
	| size box	%prec SIZE	={ size($1, $2); }
	| font box	%prec FONT	={ font($1, $2); }
	| FAT box	={ fatbox($2); }
	| SQRT box	={ sqrt($2); }
	| lpile MQ list MQ1	={ lpile('L', $1, ct); ct = $1; }
	| cpile MQ list MQ1	={ lpile('C', $1, ct); ct = $1; }
	| rpile MQ list MQ1	={ lpile('R', $1, ct); ct = $1; }
	| pile MQ list MQ1	={ lpile('-', $1, ct); ct = $1; }
	| box sub box sbox	%prec SUB	={ shift2($1, $3, $4); }
	| box sub box		%prec SUB	={ bshiftb($1, $2, $3); }
	| box sup box		%prec SUP	={ bshiftb($1, $2, $3); }
	| int sub box sbox	%prec SUB	={ integral($1, $3, $4); }
	| int sub box		%prec SUB	={ integral($1, $3, 0); }
	| int sup box		%prec SUP	={ integral($1, 0, $3); }
	| int					={ integral($1, 0, 0); }
	| left eqn right	={ paren($1, $2, $3); }
	| pbox
	| box from box tbox	%prec FROM
		={ fromto($1,$3,$4); fromflg=0; }
	| box to box	%prec TO	={ fromto($1, 0, $3); }
	| box diacrit	={ diacrit($1,$2); }
	| fwd box	%prec UP	={ move(0,$1,$2); }
	| up box	%prec UP	={ move(1,$1,$2); }
	| back box	%prec UP	={ move(2,$1,$2); }
	| down box	%prec UP	={ move(3,$1,$2); }
	| matrix MQ collist MQ1	={ matrix($1,$3); }
	;

int	: INT	={ setintegral(); }
	;

fwd	: FWD text	={ $$ = numb($1); } ;
up	: UP text	={ $$ = numb($1); } ;
back	: BACK text	={ $$ = numb($1); } ;
down	: DOWN text	={ $$ = numb($1); } ;

diacrit	: HAT	={ $$ = 'H'; }
	| VEC	={ $$ = 'V'; }
	| DYAD	={ $$ = 'Y'; }
	| BAR	={ $$ = 'B'; }
	| UNDER	={ $$ = 'N'; }	/* under bar */
	| DOT	={ $$ = 'D'; }
	| TILDE	={ $$ = 'T'; }
	| DOTDOT	={ $$ = 'U'; } /* umlaut = double dot */
	;

from	: FROM	={ $$=ps; ps =- 3;  fromflg = 1;
			if(dbg)printf(".\tfrom: old ps %d, new ps %d, fflg %d\n",
				$$,ps,fromflg);
		}
	;
to	: TO	={ $$=ps; if(fromflg==0)ps =- 3; 
			if(dbg)printf(".\tto: old ps %d, new ps %d\n",$$,ps);
		}
	;

left	: LEFT text	={ $$ = $2->c1; }
	| LEFT MQ	={ $$ = '{'; }
	;

right	: RIGHT text	={ $$ = $2->c1; }
	| RIGHT MQ1	={ $$ = '}'; }
	|		={ $$ = 0; }
	;

list	: eqn	={ lp[ct++] = $1; }
	| list ABOVE eqn	={ lp[ct++] = $3; }
	;

lpile	: LPILE	={ $$=ct; } ;
cpile	: CPILE	={ $$=ct; } ;
pile	: PILE	={ $$=ct; } ;
rpile	: RPILE	={ $$=ct; } ;

size	: SIZE text
		={	$$=ps; 
			if ($2->c1 == '+') ps =+ numb($2);
			else if ($2->c1 == '-') ps =- numb($2);
			else  ps = numb($2);
		}
	;

font	: ROMAN		={ setfont(ROM); }
	| ITALIC	={ setfont(ITAL); }
	| BOLD		={ setfont(BLD); }
	| FONT text	={ setfont($2->c1); }
	;

sub	: SUB	={ shift(1); } ;

sup	: SUP	={ shift(-1); } ;

pbox	: MQ eqn MQ1	={ $$ = $2; }
	| QTEXT	={ text('q',$1); }
	| CONTIG	={ text('c',$1); }
	| SPACE	={ text('~', $1); }
	| THIN	={ text('^', $1); }
	| TAB	={ text('\t', $1); }
	| SUM	={ funny('S'); }
	| PROD	={ funny('P'); }
/* 	| INT	={ funny('I'); } */
	| UNION	={ funny('U'); }
	| INTER	={ funny('A'); }	/* intersection */
	;

text	: CONTIG
	| QTEXT
	| SPACE	={ $$ = & "\\|\\|"; }
	| THIN	={ $$ = & "\\|"; }
	;

%%
e.h~#include <stdio.h>

#define	FATAL	1
#define	ROM	'1'
#define	ITAL	'2'
#define	BLD	'3'

#define	VERT(n)	((((n)+1)/3)*3)

extern int	dbg;
extern int	ct;
extern int	lp[];
extern int	used[];	/* available registers */
extern int	ps;	/* dflt init pt size */
extern int	deltaps;	/* default change in ps */
extern int	gsize;	/* global size */
extern int	gfont;	/* global font */
extern int	ft;	/* dflt font */
extern FILE	*curfile;	/* current input file */
extern int	ifile;	/* input file number */
extern int	linect;	/* line number in current file */
extern int	eqline;	/* line where eqn started */
extern int	svargc;
extern char	**svargv;
extern int	eht[];
extern int	ebase[];
extern int	lfont[];
extern int	rfont[];
struct { char c1; char c2; };
extern int	yyval;
extern int	*yypv;
extern int	yylval;
extern int	tht[];
extern int	tbase[];
extern int	eqnreg, eqnht;
extern int	lefteq, righteq;
extern int	lastchar;	/* last character read by lex */
re0.c~#include "e.h"
int	dbg;	/* debugging print if non-zero */
int	lp[80];	/* stack for things like piles and matrices */
int	ct;	/* pointer to lp */
int	used[100];	/* available registers */
int	ps;	/* default init point size */
int	deltaps	3;	/* default change in ps */
int	gsize	10;
int	gfont	'2';	/* italic */
int	ft;	/* default font */
FILE	*curfile;	/* current input file */
int	ifile;
int	linect;	/* line number in file */
int	eqline;	/* line where eqn started */
int	svargc;
char	**svargv;
int	eht[100];
int	ebase[100];
int	lfont[100];
int	rfont[100];
int	tht[30];
int	tbase[30];
int	eqnreg, eqnht;
int	lefteq	'\0';	/* left in-line delimiter */
int	righteq	'\0';	/* right in-line delimiter */
int	lastchar;	/* last character read by lex */
e1.c~-# include "e.h"

boverb(p1, p2) int p1, p2; {
	int h, b, treg, d;
	treg = oalloc();
	yyval = p1;
	d = (ps*6*3) / 10;	/* 0.3m */
	h = eht[p1] + eht[p2] + VERT(d);
	b = eht[p2] - d;
	if(dbg)printf(".\tb:bob: S%d <- S%d over S%d; b=%d, h=%d\n", 
		yyval, p1, p2, b, h);
	nrwid(p1, ps, p1);
	nrwid(p2, ps, p2);
	printf(".nr %d \\n(%d\n", treg, p1);
	printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2);
	printf(".nr %d \\n(%d+\\s%d.5m\\s0\n", treg, treg, ps);
	printf(".ds %d \\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d\\\n", 
		yyval, eht[p2]-ebase[p2]-d, treg, p2, p2);
	printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\*(%d\\\n", 
		p2, p1, -(eht[p2]-ebase[p2]+d+ebase[p1]), p1);
	printf("\\h'-\\n(%du-\\n(%du/2u+.1m'\\v'%du'\\l'\\n(%du-.2m'\\h'.1m'\\v'%du'\n", 
		 treg, p1, ebase[p1]+d, treg, d);
	ebase[yyval] = b;
	eht[yyval] = h;
	lfont[yyval] = rfont[yyval] = 0;
	ofree(p2);
	ofree(treg);
}

bshiftb(p1, dir, p2) int p1, dir, p2; {
	int shval, sh1, sh2, effps, effps2, d1, h1, b1, h2, b2, h;
	int diffps;
	yyval = p1;
	h1 = eht[p1]; b1 = ebase[p1];
	h2 = eht[p2]; b2 = ebase[p2];
	effps = ps>6 ? ps : 6;
	effps2 = (ps+deltaps)>6 ? ps+deltaps : 6;
	diffps = deltaps;
	sh1 = sh2 = "";
	if( dir > 0 ) {	/* subscript */
		/* top 1/2m above bottom of main box */
		d1 = VERT( (effps2*6)/2 );
		shval = - d1 + h2 - b2;
		if( d1+b1 > h2 ) /* move little sub down */
			shval = b1-b2;
		ebase[yyval] = b1 + max(0, h2-b1-d1);
		eht[yyval] = h1 + max(0, h2-b1-d1);
		if (rfont[p1] == ITAL && lfont[p2] == ROM)
			sh1 = "\\|";
		if (rfont[p2] == ITAL)
			sh2 = "\\|";
	} else {	/* superscript */
		/* 4/10 up main box */
		d1 = VERT( (effps*6*2)/10 );
		ebase[yyval] = b1;
		shval = -VERT( (4 * (h1-b1)) / 10 ) - b2;
		if( VERT(4*(h1-b1)/10) + h2 < h1-b1 )	/* raise little super */
			shval = -(h1-b1) + h2-b2 - d1;
		eht[yyval] = h1 + max(0, h2-VERT((6*(h1-b1))/10));
		if (rfont[p1] == ITAL)
			sh1 = "\\|";
	}
	if(dbg)printf(".\tb:b shift b: S%d <- S%d vert %d S%d vert %d; b=%d, h=%d\n", 
		yyval, p1, shval, p2, -shval, ebase[yyval], eht[yyval]);
	printf(".as %d \\v'%du'\\s-%d%s\\*(%d%s\\s+%d\\v'%du'\n", 
		yyval, shval, diffps, sh1, p2, sh2, diffps, -shval);
	ps =+ deltaps;
	if (rfont[p2] == ITAL)
		rfont[p1] = 0;
	else
		rfont[p1] = rfont[p2];
	ofree(p2);
}

eqnbox(p1, p2, lu) {
	int b, h, sh;
	yyval = p1;
	b = max(ebase[p1], ebase[p2]);
	eht[yyval] = h = b + max(eht[p1]-ebase[p1], 
		eht[p2]-ebase[p2]);
	ebase[yyval] = b;
	if(dbg)printf(".\te:eb: S%d <- S%d S%d; b=%d, h=%d\n", 
		yyval, p1, p2, b, h);
	if (rfont[p1] == ITAL && lfont[p2] == ROM)
		sh = "\\|";
	else
		sh = "";
	if (lu) {
		printf(".nr %d \\w'\\s%d\\*(%d%s'\n", p1, ps, p1, sh);
		printf(".ds %d \\h'|\\n(97u-\\n(%du'\\*(%d\n", p1, p1, p1);
	}
	printf(".as %d \"%s\\*(%d\n", yyval, sh, p2);
	rfont[p1] = rfont[p2];
	ofree(p2);
}

size(p1, p2) int p1, p2; {
		/* old size in p1, new in ps */
	yyval = p2;
	if(dbg)printf(".\tb:sb: S%d <- \\s%d S%d \\s%d; b=%d, h=%d\n", 
		yyval, ps, p2, p1, ebase[yyval], eht[yyval]);
	printf(".ds %d \\s%d\\*(%d\\s%d\n", 
		yyval, ps, p2, p1);
	ps = p1;
}

numb(p1) char *p1; {
	int i, n, c;
	for(i=n=0; (c=p1[i++])!='\0'; )
		if( c>='0' && c<='9' )
			n = n*10 + c-'0';
	if(dbg)printf(".\tnumb: %s %d\n", p1, n);
	return( n );
}

setfont(ch1) char ch1; {
	/* use number '1', '2', '3' for roman, italic, bold */
	yyval = ft;
	ft = ch1;
	printf(".ft %c\n", ch1);
	if(dbg)printf(".\tsetfont %c\n", ch1);
}

font(p1, p2) int p1, p2; {
		/* old font in p1, new in ft */
	yyval = p2;
	lfont[yyval] = rfont[yyval] = ft==ITAL ? ITAL : ROM;
	if(dbg)printf(".\tb:fb: S%d <- \\f%c S%d \\f%c b=%d,h=%d,lf=%c,rf=%c\n", 
		yyval, ft, p2, p1, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]);
	printf(".ds %d \\f%c\\*(%d\\f%c\n", 
		yyval, ft, p2, p1);
	ft = p1;
	printf(".ft %c\n", ft);
}

fatbox(p) int p; {
	int sh;
	yyval = p;
	sh = ps / 4;
	nrwid(p, ps, p);
	printf(".ds %d \\*(%d\\h'-\\n(%du+%du'\\*(%d\n", p, p, p, sh, p);
	if(dbg)printf(".\tfat %d, sh=%d\n", p, sh);
}

shift(p1) int p1; {
	ps =- deltaps;
	yyval = p1;
	if(dbg)printf(".\tshift: %d;ps=%d\n", yyval, ps);
}

sqrt(p2) int p2; {
	int nps;
	nps = ((eht[p2]*9)/10+5)/6;
	yyval = p2;
	eht[yyval] = VERT( (nps*6*12)/10 );
	if(dbg)printf(".\tsqrt: S%d <- S%d;b=%d, h=%d\n", 
		yyval, p2, ebase[yyval], eht[yyval]);
	if (rfont[yyval] == ITAL)
		printf(".as %d \\|\n", yyval);
	nrwid(p2, ps, p2);
	printf(".ds %d \\v'%du'\\s%d\\v'-.2m'\\(sr\\l'\\n(%du\\(rn'\\v'.2m'\\s%d", 
		yyval, ebase[p2], nps, p2, ps);
	printf("\\v'%du'\\h'-\\n(%du'\\*(%d\n", -ebase[p2], p2, p2);
}

lpile(type, p1, p2) int type, p1, p2; {
	int bi, hi, i, gap, h, b, j, nlist, nlist2, mid;
	yyval = oalloc();
	gap = VERT( (ps*6*4)/10 ); /* 4/10 m between blocks */
	if( type=='-' ) gap = 0;
	nlist = p2 - p1;
	nlist2 = (nlist+1)/2;
	mid = p1 + nlist2 -1;
	h = 0;
	for( i=p1; i<p2; i++ )
		h =+ eht[lp[i]];
	eht[yyval] = h + (nlist-1)*gap;
	b = 0;
	for( i=p2-1; i>mid; i-- )
		b =+ eht[lp[i]] + gap;
	ebase[yyval] = (nlist%2) ? b + ebase[lp[mid]]
			: b - VERT( (ps*6*5)/10 ) - gap;
	if(dbg) {
		printf(".\tS%d <- %c pile of:", yyval, type);
		for( i=p1; i<p2; i++)
			printf(" S%d", lp[i]);
		printf(";h=%d b=%d\n", eht[yyval], ebase[yyval]);
	}
	nrwid(lp[p1], ps, lp[p1]);
	printf(".nr %d \\n(%d\n", yyval, lp[p1]);
	for( i = p1+1; i<p2; i++ ) {
		nrwid(lp[i], ps, lp[i]);
		printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", 
			lp[i], yyval, yyval, lp[i]);
	}
	printf(".ds %d \\v'%du'\\h'%du*\\n(%du'\\\n", yyval, ebase[yyval], 
		type==ROM ? 1 : 0, yyval);
	for(i = p2-1; i >=p1; i--) {
		hi = eht[lp[i]]; 
		bi = ebase[lp[i]];
	switch(type) {

	case 'L':
		printf("\\v'%du'\\*(%d\\h'-\\n(%du'\\v'0-%du'\\\n", 
			-bi, lp[i], lp[i], hi-bi+gap);
		continue;
	case ROM:
		printf("\\v'%du'\\h'-\\n(%du'\\*(%d\\v'0-%du'\\\n", 
			-bi, lp[i], lp[i], hi-bi+gap);
		continue;
	case 'C':
	case '-':
		printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d", 
			-bi, yyval, lp[i], lp[i]);
		printf("\\h'-\\n(%du-\\n(%du/2u'\\v'0-%du'\\\n", 
			yyval, lp[i], hi-bi+gap);
		continue;
		}
	}
	printf("\\v'%du'\\h'%du*\\n(%du'\n", eht[yyval]-ebase[yyval]+gap, 
		type!=ROM ? 1 : 0, yyval);
	for( i=p1; i<p2; i++ )
		ofree(lp[i]);
	lfont[yyval] = rfont[yyval] = 0;
}

shift2(p1, p2, p3) int p1, p2, p3; {
	int effps, effps2, h1, h2, h3, b1, b2, b3, subsh, d1, d2, supsh;
	int treg;
	treg = oalloc();
	yyval = p1;
	if(dbg)printf(".\tshift2 s%d <- %d %d %d\n", yyval, p1, p2, p3);
	effps = (ps+deltaps)>6 ? ps+deltaps:6;
	eht[p3] = h3 = VERT( (eht[p3] * effps) / (ps>6 ? ps : 6) );
	ps =+ deltaps;
	effps2 = (ps+deltaps)>6 ? ps+deltaps:6;
	h1 = eht[p1]; b1 = ebase[p1];
	h2 = eht[p2]; b2 = ebase[p2];
	b3 = ebase[p3];
	d1 = VERT( (effps2*6)/2 );
	subsh = -d1+h2-b2;
	if( d1+b1 > h2 ) /* move little sub down */
		subsh = b1-b2;
	supsh = -VERT( (4*(h1-b1))/10 ) - b3;
	d2 = VERT( (effps*6*2)/10 );
	if( VERT(4*(h1-b1)/10)+h3 < h1-b1 )
		supsh = -(h1-b1) + (h3-b3) - d2;
	eht[yyval] = h1 + max(0, h3-VERT( (6*(h1-b1))/10 )) + max(0, h2-b1-d1);
	ebase[yyval] = b1+max(0, h2-b1-d1);
	if (rfont[p1] == ITAL && lfont[p2] == ROM)
		printf(".ds %d \\|\\*(%d\n", p2, p2);
	if (rfont[p2] == ITAL)
		printf(".as %d \\|\n", p2);
	nrwid(p2, effps, p2);
	if (rfont[p1] == ITAL && lfont[p3] == ROM)
		printf(".ds %d \\|\\|\\*(%d\n", p3, p3);
	else
		printf(".ds %d \\|\\*(%d\n", p3, p3);
	nrwid(p3, effps, p3);
	printf(".nr %d \\n(%d\n", treg, p3);
	printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2);
	printf(".as %d \\v'%du'\\s%d\\*(%d\\h'-\\n(%du'\\v'%du'\\\n", 
		p1, subsh, effps, p2, p2, -subsh+supsh);
	printf("\\s%d\\*(%d\\h'-\\n(%du+\\n(%du'\\s%d\\v'%du'\n", 
		effps, p3, p3, treg, effps2, -supsh);
	ps =+ deltaps;
	if (rfont[p2] == ITAL)
		rfont[yyval] = 0;	/* lie */
	ofree(p2); ofree(p3); ofree(treg);
}
|e2.c~# include "e.h"

fromto(p1, p2, p3) int p1, p2, p3; {
	int h, b, h1, b1, pss;
	yyval = oalloc();
	lfont[yyval] = rfont[yyval] = 0;
	h1 = eht[yyval] = eht[p1];
	b1 = ebase[p1];
	b = 0;
	pss = ps;
	ps =+ 3;
	nrwid(p1, ps, p1);
	printf(".nr %d \\n(%d\n", yyval, p1);
	if( p2>0 ) {
		nrwid(p2, pss, p2);
		printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, yyval, yyval, p2);
		eht[yyval] =+ eht[p2];
		b = eht[p2];
	}
	if( p3>0 ) {
		nrwid(p3, pss, p3);
		printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p3, yyval, yyval, p3);
		eht[yyval] =+ eht[p3];
	}
	printf(".ds %d ", yyval);	/* bottom of middle box */
	if( p2>0 ) {
		printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\s%d\\*(%d\\s%d", 
			eht[p2]-ebase[p2]+b1, yyval, p2, pss, p2, ps);
		printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\\n", 
			yyval, p2, -(eht[p2]-ebase[p2]+b1));
	}
	printf("\\h'\\n(%du-\\n(%du/2u'\\*(%d\\h'\\n(%du-\\n(%du/2u'\\\n", 
		yyval, p1, p1, yyval, p1);
	if( p3>0 ) {
		printf("\\v'%du'\\h'-\\n(%du-\\n(%du/2u'\\s%d\\*(%d\\s%d\\h'\\n(%du-\\n(%du/2u'\\v'%du'\\\n", 
			-(h1-b1+ebase[p3]), yyval, p3, pss, p3, ps, yyval, p3, (h1-b1+ebase[p3]));
	}
	printf("\n");
	ebase[yyval] = b + b1;
	if(dbg)printf(".\tfrom to: S%d <- %d f %d t %d; h=%d b=%d\n", 
		yyval, p1, p2, p3, eht[yyval], ebase[yyval]);
	ofree(p1);
	if( p2>0 ) ofree(p2);
	if( p3>0 ) ofree(p3);
}

paren(leftc, p1, rightc) int p1, leftc, rightc; {
	int n, m, h1, j, b1, v;
	h1 = eht[p1]; b1 = ebase[p1];
	yyval = p1;
	lfont[yyval] = rfont[yyval] = 0;
	n = (h1+(6*ps-1))/(6*ps);
	if( n<2 ) n = 1;
	m = n-2;
	if( leftc=='{' || rightc == '}' ){
		n = n%2 ? n : ++n;
		if( n<3 ) n=3;
		m = n-3;
	}
	eht[yyval] = VERT(6 * ps * n);
	ebase[yyval] = b1 + (eht[yyval]-h1)/2;
	v = b1 - h1/2 + VERT( (ps*6*4)/10 );
	printf(".ds %d \\|\\v'%du'", yyval, v);
	switch( leftc ) {
		case 'n':	/* nothing */
		case '\0':
			break;
		case 'f':	/* floor */
			if (n <= 1)
				printf("\\(lf");
			else
				brack(m, "\\(bv", "\\(bv", "\\(lf");
			break;
		case 'c':	/* ceiling */
			if (n <= 1)
				printf("\\(lc");
			else
				brack(m, "\\(lc", "\\(bv", "\\(bv");
			break;
		case '{':
			printf("\\b'\\(lt");
			for(j = 0; j < m; j =+ 2) printf("\\(bv");
			printf("\\(lk");
			for(j = 0; j < m; j =+ 2) printf("\\(bv");
			printf("\\(lb'");
			break;
		case '(':
			brack(m, "\\(lt", "\\(bv", "\\(lb");
			break;
		case '[':
			brack(m, "\\(lc", "\\(bv", "\\(lf");
			break;
		case '|':
			brack(m, "|", "|", "|");
			break;
		default:
			brack(m, &leftc, &leftc, &leftc);
			break;
		}
	printf("\\v'%du'\\*(%d", -v, p1);
	if( rightc ) {
		printf("\\|\\v'%du'", v);
		switch( rightc ) {
			case 'f':	/* floor */
				if (n <= 1)
					printf("\\(rf");
				else
					brack(m, "\\(bv", "\\(bv", "\\(rf");
				break;
			case 'c':	/* ceiling */
				if (n <= 1)
					printf("\\(rc");
				else
					brack(m, "\\(rc", "\\(bv", "\\(bv");
				break;
			case '}':
				printf("\\b'\\(rt");
				for(j = 0; j< m; j =+ 2)printf("\\(bv");
				printf("\\(rk");
				for(j = 0; j< m; j =+ 2) printf("\\(bv");
				printf("\\(rb'");
				break;
			case ']':
				brack(m, "\\(rc", "\\(bv", "\\(rf");
				break;
			case ')':
				brack(m, "\\(rt", "\\(bv", "\\(rb");
				break;
			case '|':
				brack(m, "|", "|", "|");
				break;
			default:
				brack(m, &rightc, &rightc, &rightc);
				break;
		}
		printf("\\v'%du'", -v);
	}
	printf("\n");
	if(dbg)printf(".\tcurly: h=%d b=%d n=%d v=%d l=%c, r=%c\n", 
		eht[yyval], ebase[yyval], n, v, leftc, rightc);
}

brack(m, t, c, b) int m; char *t, *c, *b; {
	int j;
	printf("\\b'%s", t);
	for( j=0; j<m; j++)
		printf("%s", c);
	printf("%s'", b);
}

diacrit(p1, type) int p1, type; {
	int c, t, effps;
	c = oalloc();
	t = oalloc();
	effps = ps < 6 ? 6 : ps;
	nrwid(p1, effps, p1);
	printf(".nr 10 %du\n", VERT(max(eht[p1]-ebase[p1]-6*ps,0)));	/* vertical shift if high */
	printf(".if \\n(ct>1 .nr 10 \\n(10+\\s%d.25m\\s0\n", effps);
	printf(".nr %d \\s%d.1m\\s0\n", t, effps);	/* horiz shift if high */
	printf(".if \\n(ct>1 .nr %d \\s%d.15m\\s0\n", t, effps);
	switch(type) {
		case 'V':	/* vec */
			printf(".ds %d \\v'-.4m'\\s%d\\(->\\s0\\v'.4m'\n", c, max(effps-3, 6));
			break;
		case 'Y':	/* dyad */
			printf(".ds %d \\v'-.4m'\\s%d\\z\\(<-\\(->\\s0\\v'.4m'\n", c, max(effps-3, 6));
			break;
		case 'H':	/* hat */
			printf(".ds %d ^\n", c);
			break;
		case 'T':	/* tilde */
			printf(".ds %d ~\n", c);
			break;
		case 'D':	/* dot */
			printf(".ds %d \\s%d\\v'-.67m'.\\v'.67m'\\s0\n", c, effps);
			break;
		case 'U':	/* umlaut = dotdot */
			printf(".ds %d \\s%d\\v'-.67m'..\\v'.67m\\s0'\n", c, effps);
			break;
		case 'B':	/* bar */
			printf(".ds %d \\s%d\\v'.18m'\\h'.05m'\\l'\\n(%du-.1m\\(rn'\\h'.05m'\\v'-.18m'\\s0\n",
				c, effps, p1);
			break;
		case 'N':	/* under */
			printf(".ds %d \\l'\\n(%du\\(ul'\n", c, p1);
			printf(".nr %d 0\n", t);
			printf(".nr 10 0-%d\n", -ebase[p1]);
			break;
		}
	nrwid(c, ps, c);
	if (lfont[p1] != ITAL)
		printf(".nr %d 0\n", t);
	printf(".as %d \\h'-\\n(%du-\\n(%du/2u+\\n(%du'\\v'0-\\n(10u'\\*(%d", 
		p1, p1, c, t, c);
	printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u-\\n(%du'\n", c, p1, t);
	if (type != 'N')
		eht[p1] =+ VERT( (6*ps*15) / 100);	/* 0.15m */
	if(dbg)printf(".\tdiacrit: %c over S%d, lf=%c, rf=%c, h=%d,b=%d\n",
		type, p1, lfont[p1], rfont[p1], eht[p1], ebase[p1]);
	ofree(c); ofree(t);
}

move(dir, amt, p) int dir, amt; char *p; {
	/* 0=fwd, 1=up, 2=back, 3=down */
	int a, a1, a2;
	yyval = p;
	a1 = amt/100;
	a2 = amt%100;
	printf(".ds %d ", yyval);
	if( dir==0 || dir==2 )	/* fwd, back */
		printf("\\h'%s%d.%dm'\\*(%d\n", (dir==2) ? "-" : "", a1, a2, p);
	else if (dir == 1)
		printf("\\v'-%d.%dm'\\*(%d\\v'%d.%dm'\n",
			a1, a2, p, a1, a2);
	else if (dir == 3)
		printf("\\v'%d.%dm'\\*(%d\\v'-%d.%dm'\n",
			a1, a2, p, a1, a2);
	a = (ps * 6 * amt) / 100;
/*
	if (dir == 1 || dir == 3)
		eht[yyval] =+ a;
	if( dir==1 )
		ebase[yyval] =- a;
	else if( dir==3 )
		ebase[yyval] =+ a;
*/
	if(dbg)printf(".\tmove %d dir %d amt %d; h=%d b=%d\n", 
		p, dir, amt, eht[yyval], ebase[yyval]);
}

funny(n) int n; {
	int f, t;
	yyval = oalloc();
	t = 'S';
	switch(n) {
	case 'S':
		f = "\\(*S"; break;
	case 'U':
		f = "\\(cu"; break;
	case 'A':	/* intersection */
		f = "\\(ca"; break;
	case 'P':
		f = "\\(*P"; break;
	case 'I':
		f = "\\(is";
		t = 'I';
		printf(".ds %d \\s%d\\v'.1m'\\s+4%s\\s-4\\v'-.1m'\\s%d\n", 
			yyval, ps, f, ps);
		eht[yyval] = VERT( (((ps+4)*12)/10)*6 );
		ebase[yyval] = VERT( (ps*6*3)/10 );
		break;
	default:
		t = 0;
	}
	if( t == 'S' ) {
		printf(".ds %d \\s%d\\v'.3m'\\s+5%s\\s-5\\v'-.3m'\\s%d\n", 
			yyval, ps, f, ps);
		eht[yyval] = VERT( (ps+5)*6 -(ps*6*2)/10 );
		ebase[yyval] = VERT( (ps*6*3)/10 );
	}
	if(dbg)printf(".\tfunny: S%d <- %s; h=%d b=%d\n", 
		yyval, f, eht[yyval], ebase[yyval]);
	lfont[yyval] = rfont[yyval] = ROM;
}


integral(p, p1, p2) {
	if (p1 != 0)
		printf(".ds %d \\h'-0.4m'\\v'0.4m'\\*(%d\\v'-0.4m'\n", p1, p1);
	if (p2 != 0)
		printf(".ds %d \\v'-0.3m'\\*(%d\\v'0.3m'\n", p2, p2);
	if (p1 != 0 & p2 != 0)
		shift2(p, p1, p2);
	else if (p1 != 0)
		bshiftb(p, 1, p1);
	else if (p2 != 0)
		bshiftb(p, -1, p2);
	if(dbg)printf(".\tintegral: S%d; h=%d b=%d\n", 
		p, eht[p], ebase[p]);
	lfont[p] = ROM;
}

setintegral() {
	int f;
	yyval = oalloc();
	f = "\\(is";
	printf(".ds %d \\s%d\\v'.1m'\\s+4%s\\s-4\\v'-.1m'\\s%d\n", 
		yyval, ps, f, ps);
	eht[yyval] = VERT( (((ps+4)*12)/10)*6 );
	ebase[yyval] = VERT( (ps*6*3)/10 );
	lfont[yyval] = rfont[yyval] = ROM;
}
e3.c~# include "e.h"

struct {
	char	*res;
	char	*resval;
} restab[] {
	">=",	"\\(>=",
	"<=",	"\\(<=",
	"==",	"\\(==",
	"!=",	"\\(!=",
	"+-",	"\\(+-",
	"->",	"\\(->",
	"<-",	"\\(<-",
	"<<",	"<\\h'-.3m'<",
	">>",	">\\h'-.3m'>",
	"inf",	"\\(if",
	"infinity",	"\\(if",
	"partial",	"\\(pd",
	"half",	"\\fR\\(12\\fP",
	"prime",	"\\fR\\(fm\\fP",
	"approx",	"\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'",
	"nothing",	"",
	"cdot",	"\\v'-.3m'.\\v'.3m'",
	"times",	"\\(mu",
	"del",	"\\(gr",
	"grad",	"\\(gr",
	"...",	"\\v'-.3m'\\ .\\ .\\ .\\ \\v'.3m'",
	",...,",	",\\ .\\ .\\ .\\ ,\\|",

	"alpha",	"\\(*a",
	"beta",	"\\(*b",
	"gamma",	"\\(*g",
	"GAMMA",	"\\(*G",
	"delta",	"\\(*d",
	"DELTA",	"\\(*D",
	"epsilon",	"\\(*e",
	"omega",	"\\(*w",
	"OMEGA",	"\\(*W",
	"lambda",	"\\(*l",
	"LAMBDA",	"\\(*L",
	"mu",	"\\(*m",
	"nu",	"\\(*n",
	"theta",	"\\(*h",
	"THETA",	"\\(*H",
	"phi",	"\\(*f",
	"PHI",	"\\(*F",
	"pi",	"\\(*p",
	"PI",	"\\(*P",
	"sigma",	"\\(*s",
	"SIGMA",	"\\(*S",
	"xi",	"\\(*c",
	"XI",	"\\(*C",
	"zeta",	"\\(*z",
	"iota",	"\\(*i",
	"eta",	"\\(*y",
	"kappa",	"\\(*k",
	"rho",	"\\(*r",
	"tau",	"\\(*t",
	"omicron",	"\\(*o",
	"upsilon",	"\\(*u",
	"UPSILON",	"\\(*U",
	"psi",	"\\(*q",
	"PSI",	"\\(*Q",
	"chi",	"\\(*x",
	"and",	"\\fRand\\fP",
	"for",	"\\fRfor\\fP",
	"if",	"\\fRif\\fP",
	"Re",	"\\fRRe\\fP",
	"Im",	"\\fRIm\\fP",
	"sin",	"\\fRsin\\fP",
	"cos",	"\\fRcos\\fP",
	"tan",	"\\fRtan\\fP",
	"arc",	"\\fRarc\\fP",
	"sinh",	"\\fRsinh\\fP",
	"coth",	"\\fRcoth\\fP",
	"tanh",	"\\fRtanh\\fP",
	"cosh",	"\\fRcosh\\fP",
	"lim",	"\\fRlim\\fP",
	"log",	"\\fRlog\\fP",
	"max",	"\\fRmax\\fP",
	"min",	"\\fRmin\\fP",
	"ln",	"\\fRln\\fP",
	"exp",	"\\fRexp\\fP",
	"det",	"\\fRdet\\fP",
	0,	0
};

int	csp;
int	psp;
#define	CSSIZE	400
char	cs[420];

int	lf, rf;	/* temporary spots for left and right fonts */

text(t,p1) int t; char *p1; {
	int i,j,c;
	yyval = oalloc();
	ebase[yyval] = 0;
	eht[yyval] = VERT(6 * ((ps>6)?ps:6));	/* ht in machine units */
	lfont[yyval] = rfont[yyval] = ROM;
	if( t=='q' )
		j = p1;
	else if ( t == '~' )
		j = &"\\|\\|";
	else if ( t == '^' )
		j = &"\\|";
	else if ( t == '\t' )
		j = &"\\t";
	else if( (i=lookup(p1,restab))>=0 ) {
		j = restab[i].resval;
	}
	else {
		lf = rf = 0;
		for( csp=psp=0; (c=p1[psp++])!='\0'; ){
			rf = trans(c, p1);
			if (lf == 0)
				lf = rf;	/* save first */
			if( csp>CSSIZE )
				error(FATAL,"converted token %.25s... too long",p1);
		}
		cs[csp] = '\0';
		j = cs;
		lfont[yyval] = lf;
		rfont[yyval] = rf;
	}
	if(dbg)printf(".\t%ctext: S%d <- %s; b=%d,h=%d,lf=%c,rf=%c\n",
		t, yyval, j, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]);
	printf(".ds %d \"%s\n", yyval, j);
}

trans(c,p1) int c; char *p1; {
	int f;
	f = ROM;
	switch( c){
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	case ':': case ';': case '!': case '%':
	case '(': case '[': case ')': case ']':
		if (rf == ITAL)
			shim();
		roman(c); break;
	case '.':
		if (rf == ROM)
			roman(c);
		else
			cs[csp++] = c;
		f = rf;
		break;
	case '|':
		if (rf == ITAL)
			shim();
		shim(); roman(c); shim(); break;
	case '=':
		if (rf == ITAL)
			shim();
		name4('e','q');
		break;
	case '+':
		if (rf == ITAL)
			shim();
		name4('p', 'l');
		break;
	case '>': case '<':
		if (rf == ITAL)
			shim();
		if( p1[psp]=='=' ){	/* look ahead for == <= >= */
			name4(c,'=');
			psp++;
		} else {
			cs[csp++] = c;  
		}
		break;
	case '-':
		if (rf == ITAL)
			shim();
		if( p1[psp]=='>' ){
			name4('-','>'); psp++;
		} else {
			name4('m','i');
		}
		break;
	case '/':
		if (rf == ITAL)
			shim();
		name4('s','l');
		break;
	case '~': case ' ':
		shim(); shim(); break;
	case '^':
		shim(); break;
	case '\\':	/* troff - pass 2 or 3 more chars */
		if (rf == ITAL)
			shim();
		cs[csp++] = c; cs[csp++] = c = p1[psp++]; cs[csp++] = p1[psp++];
		if( c=='(' ) cs[csp++] = p1[psp++];
		if( c=='*' && cs[csp-1] == '(' ){
			cs[csp++] = p1[psp++];
			cs[csp++] = p1[psp++];
		}
		break;
	case '\'':
		cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = rf==ITAL ? ITAL : ROM;
		name4('f','m');
		cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P';
		f = rf==ITAL ? ITAL : ROM;
		break;
	case 'f':

		if (ft == ITAL) {
			cs[csp++] = '\\'; cs[csp++] = '^';
			cs[csp++] = 'f';
			cs[csp++] = '\\'; cs[csp++] = '^';
			f = ITAL;
		}
		else
			cs[csp++] = 'f';
		break;
	case 'j':
		if (ft == ITAL) {
			cs[csp++] = '\\'; cs[csp++] = '^';
			cs[csp++] = 'j';
			f = ITAL;
		}
		else
			cs[csp++] = 'j';
		break;
	default:
		cs[csp++] = c;
		f = ft==ITAL ? ITAL : ROM;
		break;
	}
	return(f);
}

shim() {
	cs[csp++] = '\\'; cs[csp++] = '|';
}

roman(c) int c; {
	cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = ROM;
	cs[csp++] = c;
	cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P';
}

name4(c1,c2) int c1,c2; {
	cs[csp++] = '\\';
	cs[csp++] = '(';
	cs[csp++] = c1;
	cs[csp++] = c2;
}
e4.c~# include "e.h"
# define	SIGPIPE	13	/* troff has stopped reading */
#define	MAXLINE	600	/* maximum input line */

char	in[MAXLINE];	/* input buffer */
int	eqnexit();
int noeqn;

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

	eqnexit(eqn(argc, argv));
}

eqnexit(n) {
#ifdef gcos
	if (n)
		fprintf(stderr, "run terminated due to eqn error\n");
	exit(0);
#endif
	exit(n);
}

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

#ifdef unix
	signal(SIGPIPE, &eqnexit);
#endif

	setfile(argc,argv);
	while ((type=getline(in)) != EOF) {
		eqline = linect;
		if (in[0]=='.' && in[1]=='E' && in[2]=='Q') {
			for (i=11; i<100; used[i++]=0);
			printf("%s",in);
			printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n");
			init();
			yyparse();
			if (eqnreg>0) {
				printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg);
				printf(".if \\n(%d>\\n(.l .tm too-long eqn, file %s, between lines %d-%d\n",
					eqnreg, svargv[ifile], eqline, linect);
				printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht);
				printf(".rn %d 10\n", eqnreg);
				if(!noeqn)printf("\\*(10\n");
			}
			printf(".ps \\n(99\n.ft \\n(98\n");
			printf(".EN");
			if (lastchar == EOF) {
				putchar('\n');
				break;
			}
			if (putchar(lastchar) != '\n')
				while (putchar(gtc()) != '\n');
		}
		else if (type == lefteq)
			inline();
		else
			printf("%s",in);
	}
	return(0);
}

getline(s) char *s; {
	char c;
	while((*s++=c=gtc())!='\n' && c!=EOF && c!=lefteq)
		if (s >= in+MAXLINE) {
			error( !FATAL, "input line too long: %.20s\n", in);
			in[MAXLINE] = '\0';
			break;
		}
	if (c==lefteq)
		s--;
	*s++ = '\0';
	return(c);
}

inline() {
	int i,j,ds,t;
	printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n");
	ds = oalloc();
	printf(".rm %d \n", ds);
	do{
		if (*in)
			printf(".as %d \"%s\n", ds, in);
		init();
		yyparse();
		if (eqnreg > 0) {
			printf(".as %d \\*(%d\n", ds, eqnreg);
			ofree(eqnreg);
		}
		printf(".ps \\n(99\n.ft \\n(98\n");
	} while ((t=getline(in)) == lefteq);
	if (*in)
		printf(".as %d \"%s", ds, in);
	printf(".ps \\n(99\n.ft \\n(98\n");
	printf("\\*(%d\n", ds);
	ofree(ds);
}

putout(p1) int p1; {
	extern int gsize, gfont;
	int before, after;
	if(dbg)printf(".\tanswer <- S%d, h=%d,b=%d\n",p1, eht[p1], ebase[p1]);
	eqnht = eht[p1];
	printf(".ds %d \\x'0'", p1);
	/* suppposed to leave room for a subscript or superscript */
	before = eht[p1] - ebase[p1] - VERT((ps*6*12)/10);
	if (before > 0)
		printf("\\x'0-%du'", before);
	printf("\\f%c\\s%d\\*(%d\\s\\n(99\\f\\n(98",gfont,gsize,p1);
	after = ebase[p1] - VERT((ps*6*2)/10);
	if (after > 0)
		printf("\\x'%du'", after);
	putchar('\n');
	eqnreg = p1;
}

max(i,j) int i,j; {
	return (i>j ? i : j);
}

oalloc() {
	int i;
	for (i=11; i<100; i++)
		if (used[i]++ == 0) return(i);
	error( FATAL, "no eqn strings left", i);
}

ofree(n) int n; {
	used[n] = 0;
}

setps(p) int p; {
	printf(".ps %d\n", p);
}

nrwid(n1, p, n2) int n1, p, n2; {
	printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, p, n2);
}

setfile(argc, argv) int argc; char *argv[]; {
	svargc = --argc;
	svargv = argv;
	while (svargc > 0 && svargv[1][0] == '-') {
		switch (svargv[1][1]) {

		case 'd': lefteq=svargv[1][2]; righteq=svargv[1][3]; break;
		case 's': gsize = numb(&svargv[1][2]); break;
		case 'p': deltaps = numb(&svargv[1][2]); break;
		case 'f': gfont = svargv[1][2]; break;
		case 'e': noeqn++; break;
		default: dbg = 1;
		}
		svargc--;
		svargv++;
	}
	ifile = 1;
	linect = 1;
	if (svargc <= 0)
		curfile = stdin;
	else if ((curfile = fopen(svargv[1], "r")) == NULL)
		error( FATAL,"can't open file %s", svargv[1]);
}

yyerror() {;}

init() {
	ct = 0;
	ps = gsize;
	ft = gfont;
	setps(ps);
	printf(".ft %c\n", ft);
}

error(fatal, s1, s2) int fatal; char *s1, *s2; {
	if (fatal>0)
		printf("eqn fatal error: ");
	printf(s1,s2);
	printf("\nfile %s, between lines %d and %d\n",
		 svargv[ifile], eqline, linect);
	fprintf(stderr, "eqn: ");
	if (fatal>0)
		fprintf(stderr, "fatal error: ");
	fprintf(stderr, s1, s2);
	fprintf(stderr, "\nfile %s, between lines %d and %d\n",
		 svargv[ifile], eqline, linect);
	if (fatal > 0)
		eqnexit(1);
}
e5.c~#include "e.h"

mark(p1) int p1; {
	printf(".ds %d \\k(97\\*(%d\n", p1, p1);
	yyval = p1;
	if(dbg)printf(".\tmark %d\n", p1);
}

lineup(p1, p2) {
	yyval = oalloc();
	printf(".ds %d \\h'|\\n(97u'\n", yyval);
	if(dbg)printf(".\tlineup %d and %d\n", p1, p2);
}
e6.c~6#include "e.h"

column(type, p1, p2) int type, p1, p2; {
	int i, n;
	lp[p1] = ct - p1 - 1;
	if( dbg ){
		printf(".\t%c column of", type);
		for( i=p1+1; i<ct; i++ )
			printf(" S%d", lp[i]);
		printf(", rows=%d\n",lp[p1]);
	}
	lp[ct++] = type;
}

matrix(p1,p2) int p1, p2; {
	int nrow, ncol, i, j, k, hb, b, val[100], db;
	char *space;
	space = "\\ \\ ";
	nrow = lp[p1];	/* disaster if rows inconsistent */
	ncol = 0;
	for( i=p1; i<ct; i =+ lp[i]+2 ){
		ncol++;
		if(dbg)printf(".\tcolct=%d\n",lp[i]);
	}
	for( k=1; k<=nrow; k++ ) {
		hb = b = 0;
		j = p1 + k;
		for( i=0; i<ncol; i++ ) {
			hb = max(hb, eht[lp[j]]-ebase[lp[j]]);
			b = max(b, ebase[lp[j]]);
			j =+ nrow + 2;
		}
		if(dbg)printf(".\trow %d: b=%d, hb=%d\n", k, b, hb);
		j = p1 + k;
		for( i=0; i<ncol; i++ ) {
			ebase[lp[j]] = b;
			eht[lp[j]] = b + hb;
			j =+ nrow + 2;
		}
	}
	j = p1;
	for( i=0; i<ncol; i++ ) {
		lpile(lp[j+lp[j]+1], j+1, j+lp[j]+1);
		val[i] = yyval;
		j =+ nrow + 2;
	}
	yyval = oalloc();
	eht[yyval] = eht[val[0]];
	ebase[yyval] = ebase[val[0]];
	lfont[yyval] = rfont[yyval] = 0;
	if(dbg)printf(".\tmatrix S%d: r=%d, c=%d, h=%d, b=%d\n",
		yyval,nrow,ncol,eht[yyval],ebase[yyval]);
	printf(".ds %d \"", yyval);
	for( i=0; i<ncol; i++ )  {
		printf("\\*(%d%s", val[i], i==ncol-1 ? "" : space);
		ofree(val[i]);
	}
	printf("\n");
	ct = p1;
}
elex.c~`#include "e.h"
#include "y.tab.c"

#define	MAXDEFS	200	/* max number of definitions */
struct {
	char *nptr;	/* name pointer */
	char *sptr;	/* defining string */
} deftab[MAXDEFS];
int	defptr	0;	/* next free slot in deftab */

struct	{
	char	*key;
	int	keyval;
} keytab[] {
	"sub",	SUB,
	"sup",	SUP,
	".EN",	0,
	"from",	FROM,
	"to",	TO,
	"sum",	SUM,
	"hat",	HAT,
	"vec", VEC,
	"dyad", DYAD,
	"dot",	DOT,
	"dotdot",	DOTDOT,
	"bar",	BAR,
	"tilde",	TILDE,
	"under",	UNDER,
	"prod",	PROD,
	"int",	INT,
	"integral",	INT,
	"union",	UNION,
	"inter",	INTER,
	"pile",	PILE,
	"lpile",	LPILE,
	"cpile",	CPILE,
	"rpile",	RPILE,
	"over",	OVER,
	"sqrt",	SQRT,
	"above",	ABOVE,
	"size",	SIZE,
	"font",	FONT,
	"fat", FAT,
	"roman",	ROMAN,
	"italic",	ITALIC,
	"bold",	BOLD,
	"left",	LEFT,
	"right",	RIGHT,
	"delim",	DELIM,
	"define",	DEFINE,
	"tdefine",	DEFINE,
	"ndefine",	NDEFINE,
	"gsize",	GSIZE,
	".gsize",	GSIZE,
	"gfont",	GFONT,
	"include",	INCLUDE,
	"up",	UP,
	"down",	DOWN,
	"fwd",	FWD,
	"back",	BACK,
	"mark",	MARK,
	"lineup",	LINEUP,
	"matrix",	MATRIX,
	"col",	COL,
	"lcol",	LCOL,
	"ccol",	CCOL,
	"rcol",	RCOL,
	0,	0
};
#define	SSIZE	400
char	token[SSIZE];
int	sp;
#define	putbak(c)	*ip++ = c;
#define	PUSHBACK	300	/* maximum pushback characters */
char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
char	*ip	ibuf;

gtc() {
  loop:
	if (ip > ibuf)
		return(*--ip);	/* already present */
	lastchar = getc(curfile);
	if (lastchar=='\n')
		linect++;
	if (lastchar != EOF)
		return(lastchar);
	if (++ifile > svargc) {
		return(EOF);
	}
	fclose(curfile);
	linect = 1;
	if ((curfile=fopen(svargv[ifile],"r")) != NULL)
		goto loop;
	error(FATAL,"can't open file %s\n", svargv[ifile]);
}

pbstr(str)
register char *str;
{
	register char *p;

	p = str;
	while (*p++);
	--p;
	if (ip >= &ibuf[PUSHBACK])
		error( FATAL, "eqn pushback overflow\n");
	while (p > str)
		putbak(*--p);
}

yylex() {
	int c, type;
  beg:
	while ((c=gtc())==' ' || c=='\n');
	yylval=c;
	switch(c) {

	case EOF:
		return('\0');
	case '~':
		return(SPACE);
	case '^':
		return(THIN);
	case '\t':
		return(TAB);
	case '{':
		return(MQ);
	case '}':
		return(MQ1);
	case '"':
		for (sp=0; (c=gtc())!='"'; ) {
			if(c !='\\')token[sp++]=c;
			else { if((c=gtc())!= '"')token[sp++]='\\';
				token[sp++] = c; }
			if (sp>=SSIZE)
				error(FATAL,"quoted string %.20s... too long", token);
		}
		token[sp]='\0';
		yylval= &token[0];
		return(QTEXT);
	}
	if (c==righteq)
		return('\0');

	getstr(token, c);
	if(dbg)printf(".\tlex token = |%s|\n", token);
	if((type = lookup(token,deftab)) >= 0) {
		putbak(' ');
		pbstr(deftab[type].sptr);
		putbak(' ');
		if(dbg)
			printf(".\tfound %s=|%s|\n", token, deftab[type].sptr);
		goto beg;
		}
	type = lookup(token,keytab);
	if (type < 0)
		return(CONTIG);
	switch (keytab[type].keyval) {

	case DEFINE: case NDEFINE:
		define(keytab[type].keyval);
		goto beg;
	case DELIM:
		delim();
		goto beg;
	case GSIZE:
		globsize();
		goto beg;
	case GFONT:
		globfont();
		goto beg;
	case INCLUDE:
		include();
		goto beg;
	default:
		return( keytab[type].keyval );
	}
}

getstr(s,c) char *s, c; {
	for (sp=0; c!=' ' && c!='\t' && c!='\n' && c!='{' && c!='}'
		&& c!='"' && c!='~' && c!='^' && c!=righteq; ) {
		if(c == '\\') if((c = gtc()) != '"')s[sp++] = '\\';
		s[sp++] = c;
		if (sp>=SSIZE)
			error(FATAL,"token %.20s... too long",s);
		c = gtc();
		}
	if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
		putbak(c);
	s[sp]='\0';
	yylval = s;
}

lookup(str,tbl)
char *str;
struct { char *name; char *val; } tbl[];
{
	register i,j, r;
	for (i=0; tbl[i].name!=0; i++) { /* table of tbl wds */
		for ( j=0; (r=tbl[i].name[j])==str[j] && r!='\0'; j++);
		if (r == str[j])
			return(i);
	}
	return( -1 );
}

cstr(s,quote) char *s; int quote; {
	int del,c,i;
	while((del=gtc()) == ' ' || del == '\t' || del == '\n');
	if(quote)
		for (i=0; (c=gtc()) != del;)
			s[i++] = c;
	else {
		s[0] = del;
		for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n';)
			s[i++]=c;
	}
	s[i] = '\0';
	return(s);
}

define(type) int type; {
	/*	char *calloc (); */
	int i, c, index;
	while ((c=gtc())==' ' || c=='\n');
	getstr(token,c);
	if (type == DEFINE) {
		if((index = lookup(token,deftab)) >= 0) {
			cfree(deftab[index].sptr);
		} else {
			index = defptr++;
			if (index >= MAXDEFS)
				error(FATAL, "Too many definitions at %s\n", token);
			for (i=0; token[i] != '\0'; i++);
			deftab[index].nptr = calloc(i+1,1);
			for (i=0; deftab[index].nptr[i]=token[i]; i++);
		}
		if(dbg)printf(".\tdefine %s\n",deftab[index].nptr);
	}
	cstr(token,1);
	if (type != DEFINE)
		return;
	for (i=0; token[i] != '\0'; i++);
	deftab[index].sptr = calloc(i+1,1);
	for (i=0; deftab[index].sptr[i] = token[i]; i++);
	if(dbg)printf(".\tname %s defined as %s\n",
		deftab[index].nptr, deftab[index].sptr);
}

include() {
	error(!FATAL, "Include not yet implemented\n");
}

delim() {
	char *s;
	yyval = eqnreg = 0;
	cstr(token,0);
	lefteq = token[0];
	righteq = token[1];
	if (lefteq == 'o' && righteq == 'f')
		lefteq = righteq = '\0';
}

globsize() {
	extern int gsize;
	int c;
	while ((c=gtc())==' ' || c=='\n');
	getstr(token,c);
	if (token[0] == '+')
		gsize =+ numb(token);
	else if (token[0] == '-')
		gsize =- numb(token);
	else
		gsize = numb(token);
	yyval = eqnreg = 0;
	setps(gsize);
	ps = gsize;
	if (gsize >= 12)	/* sub and sup size change */
		deltaps = gsize / 4;
	else
		deltaps = gsize / 3;
}

globfont() {
	extern int gfont;
	while ((gfont=gtc())==' ' || gfont=='\n');
	getstr(token, gfont);
	yyval = eqnreg = 0;
	switch (gfont) {
	case 'r': case 'R':
		gfont = '1';
		break;
	case 'i': case 'I':
		gfont = '2';
		break;
	case 'b': case 'B':
		gfont = '3';
		break;
	}
	printf(".ft %c\n", gfont);
	ft = gfont;
}