BSD 4_1c_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Tue, 8 Jun 1982 14:00:16 +0000 (06:00 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Tue, 8 Jun 1982 14:00:16 +0000 (06:00 -0800)
Work on file usr/src/usr.bin/eqn/diacrit.c
Work on file usr/src/usr.bin/eqn/e.y
Work on file usr/src/usr.bin/eqn/Makefile
Work on file usr/src/usr.bin/eqn/e.h
Work on file usr/src/usr.bin/eqn/fromto.c
Work on file usr/src/usr.bin/eqn/font.c
Work on file usr/src/usr.bin/eqn/eqnbox.c
Work on file usr/src/usr.bin/eqn/glob.c
Work on file usr/src/usr.bin/eqn/integral.c
Work on file usr/src/usr.bin/eqn/funny.c
Work on file usr/src/usr.bin/eqn/io.c
Work on file usr/src/usr.bin/eqn/lookup.c
Work on file usr/src/usr.bin/eqn/lex.c
Work on file usr/src/usr.bin/eqn/mark.c
Work on file usr/src/usr.bin/eqn/over.c
Work on file usr/src/usr.bin/eqn/matrix.c
Work on file usr/src/usr.bin/eqn/move.c
Work on file usr/src/usr.bin/eqn/pile.c
Work on file usr/src/usr.bin/eqn/size.c
Work on file usr/src/usr.bin/eqn/paren.c
Work on file usr/src/usr.bin/eqn/shift.c
Work on file usr/src/usr.bin/eqn/sqrt.c
Work on file usr/src/usr.bin/eqn/text.c
Work on file usr/src/usr.bin/eqn/lookup.old.c

Synthesized-from: CSRG/cd1/4.1c.2

24 files changed:
usr/src/usr.bin/eqn/Makefile [new file with mode: 0644]
usr/src/usr.bin/eqn/diacrit.c [new file with mode: 0644]
usr/src/usr.bin/eqn/e.h [new file with mode: 0644]
usr/src/usr.bin/eqn/e.y [new file with mode: 0644]
usr/src/usr.bin/eqn/eqnbox.c [new file with mode: 0644]
usr/src/usr.bin/eqn/font.c [new file with mode: 0644]
usr/src/usr.bin/eqn/fromto.c [new file with mode: 0644]
usr/src/usr.bin/eqn/funny.c [new file with mode: 0644]
usr/src/usr.bin/eqn/glob.c [new file with mode: 0644]
usr/src/usr.bin/eqn/integral.c [new file with mode: 0644]
usr/src/usr.bin/eqn/io.c [new file with mode: 0644]
usr/src/usr.bin/eqn/lex.c [new file with mode: 0644]
usr/src/usr.bin/eqn/lookup.c [new file with mode: 0644]
usr/src/usr.bin/eqn/lookup.old.c [new file with mode: 0644]
usr/src/usr.bin/eqn/mark.c [new file with mode: 0644]
usr/src/usr.bin/eqn/matrix.c [new file with mode: 0644]
usr/src/usr.bin/eqn/move.c [new file with mode: 0644]
usr/src/usr.bin/eqn/over.c [new file with mode: 0644]
usr/src/usr.bin/eqn/paren.c [new file with mode: 0644]
usr/src/usr.bin/eqn/pile.c [new file with mode: 0644]
usr/src/usr.bin/eqn/shift.c [new file with mode: 0644]
usr/src/usr.bin/eqn/size.c [new file with mode: 0644]
usr/src/usr.bin/eqn/sqrt.c [new file with mode: 0644]
usr/src/usr.bin/eqn/text.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/eqn/Makefile b/usr/src/usr.bin/eqn/Makefile
new file mode 100644 (file)
index 0000000..8843a9d
--- /dev/null
@@ -0,0 +1,34 @@
+CFLAGS=-O -d2
+YFLAGS=-d
+
+SOURCE = e.y e.h diacrit.c eqnbox.c font.c fromto.c funny.c glob.c integral.c \
+ io.c lex.c lookup.c mark.c matrix.c move.c over.c paren.c \
+ pile.c shift.c size.c sqrt.c text.c
+
+FILES = e.o diacrit.o eqnbox.o font.o fromto.o funny.o glob.o integral.o \
+ io.o lex.o lookup.o mark.o matrix.o move.o over.o paren.o \
+ pile.o shift.o size.o sqrt.o text.o
+
+eqn:   $(FILES)
+       cc $(CFLAGS) $(FILES) -o eqn
+
+e.c:   e.def
+
+e.def: e.y
+       yacc -d e.y
+       mv y.tab.c e.c
+       mv y.tab.h e.def
+
+$(FILES):      e.h e.def
+
+install: eqn
+       install -s eqn $(DESTDIR)/usr/bin
+
+clean:
+       rm -f *.o e.c e.def eqn
+       
+list:
+       pr TODO $(SOURCE) makefile
+
+lint:  y.tab.c
+       lint -spb *.c
diff --git a/usr/src/usr.bin/eqn/diacrit.c b/usr/src/usr.bin/eqn/diacrit.c
new file mode 100644 (file)
index 0000000..236868f
--- /dev/null
@@ -0,0 +1,56 @@
+# include "e.h"
+# include "e.def"
+
+diacrit(p1, type) int p1, type; {
+       int c, t, effps;
+
+       c = oalloc();
+       t = oalloc();
+       effps = EFFPS(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 VEC:
+                       printf(".ds %d \\v'-.4m'\\s%d\\(->\\s0\\v'.4m'\n", c, max(effps-3, 6));
+                       break;
+               case DYAD:
+                       printf(".ds %d \\v'-.4m'\\s%d\\z\\(<-\\(->\\s0\\v'.4m'\n", c, max(effps-3, 6));
+                       break;
+               case HAT:
+                       printf(".ds %d ^\n", c);
+                       break;
+               case TILDE:
+                       printf(".ds %d ~\n", c);
+                       break;
+               case DOT:
+                       printf(".ds %d \\s%d\\v'-.67m'.\\v'.67m'\\s0\n", c, effps);
+                       break;
+               case DOTDOT:
+                       printf(".ds %d \\s%d\\v'-.67m'..\\v'.67m\\s0'\n", c, effps);
+                       break;
+               case 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 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);
+       /* BUG - should go to right end of widest */
+       if (type != UNDER)
+               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);
+}
diff --git a/usr/src/usr.bin/eqn/e.h b/usr/src/usr.bin/eqn/e.h
new file mode 100644 (file)
index 0000000..54fa047
--- /dev/null
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+#define        FATAL   1
+#define        ROM     '1'
+#define        ITAL    '2'
+#define        BLD     '3'
+
+#define        VERT(n) ((((n)+1)/3)*3)
+#define        EFFPS(p)        ((p) >= 6 ? (p) : 6)
+
+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[];
+extern int     yyval;
+extern int     *yypv;
+extern int     yylval;
+extern int     eqnreg, eqnht;
+extern int     lefteq, righteq;
+extern int     lastchar;       /* last character read by lex */
+extern int     markline;       /* 1 if this EQ/EN contains mark or lineup */
+
+typedef struct s_tbl {
+       char    *name;
+       char    *defn;
+       struct s_tbl *next;
+} tbl;
diff --git a/usr/src/usr.bin/eqn/e.y b/usr/src/usr.bin/eqn/e.y
new file mode 100644 (file)
index 0000000..f294e59
--- /dev/null
@@ -0,0 +1,166 @@
+%{#
+#include "e.h"
+#
+int    fromflg;
+%}
+%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  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); }
+       ;
+
+lineupbox: LINEUP box  { $$ = $2; lineup(1); }
+       ;
+
+matrix : MATRIX        { $$ = ct; } ;
+
+collist        : column
+       | collist column
+       ;
+
+column : lcol '{' list '}'     { column('L', $1); }
+       | ccol '{' list '}'     { column('C', $1); }
+       | rcol '{' list '}'     { column('R', $1); }
+       | col '{' list '}'      { column('-', $1); }
+       ;
+
+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 '{' list '}'    { lpile('L', $1, ct); ct = $1; }
+       | cpile '{' list '}'    { lpile('C', $1, ct); ct = $1; }
+       | rpile '{' list '}'    { lpile('R', $1, ct); ct = $1; }
+       | pile '{' list '}'     { 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(FWD, $1, $2); }
+       | up box        %prec UP        { move(UP, $1, $2); }
+       | back box      %prec UP        { move(BACK, $1, $2); }
+       | down box      %prec UP        { move(DOWN, $1, $2); }
+       | matrix '{' collist '}'        { matrix($1); }
+       ;
+
+int    : INT   { setintegral(); }
+       ;
+
+fwd    : FWD text      { $$ = atoi((char *) $1); } ;
+up     : UP text       { $$ = atoi((char *) $1); } ;
+back   : BACK text     { $$ = atoi((char *) $1); } ;
+down   : DOWN text     { $$ = atoi((char *) $1); } ;
+
+diacrit        : HAT   { $$ = HAT; }
+       | VEC   { $$ = VEC; }
+       | DYAD  { $$ = DYAD; }
+       | BAR   { $$ = BAR; }
+       | UNDER { $$ = UNDER; } /* under bar */
+       | DOT   { $$ = DOT; }
+       | TILDE { $$ = TILDE; }
+       | DOTDOT        { $$ = DOTDOT; } /* 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     { $$ = ((char *)$2)[0]; }
+       | LEFT '{'      { $$ = '{'; }
+       ;
+
+right  : RIGHT text    { $$ = ((char *)$2)[0]; }
+       | RIGHT '}'     { $$ = '}'; }
+       |               { $$ = 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; setsize((char *) $2); }
+       ;
+
+font   : ROMAN         { setfont(ROM); }
+       | ITALIC        { setfont(ITAL); }
+       | BOLD          { setfont(BLD); }
+       | FONT text     { setfont(((char *)$2)[0]); }
+       ;
+
+sub    : SUB   { shift(SUB); }
+       ;
+
+sup    : SUP   { shift(SUP); }
+       ;
+
+pbox   : '{' eqn '}'   { $$ = $2; }
+       | QTEXT         { text(QTEXT, (char *) $1); }
+       | CONTIG        { text(CONTIG, (char *) $1); }
+       | SPACE         { text(SPACE, 0); }
+       | THIN          { text(THIN, 0); }
+       | TAB           { text(TAB, 0); }
+       | SUM           { funny(SUM); }
+       | PROD          { funny(PROD); }
+       | UNION         { funny(UNION); }
+       | INTER         { funny(INTER); }       /* intersection */
+       ;
+
+text   : CONTIG
+       | QTEXT
+       ;
+
+%%
diff --git a/usr/src/usr.bin/eqn/eqnbox.c b/usr/src/usr.bin/eqn/eqnbox.c
new file mode 100644 (file)
index 0000000..2aea8da
--- /dev/null
@@ -0,0 +1,25 @@
+# include "e.h"
+
+eqnbox(p1, p2, lu) {
+       int b, h;
+       char *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);
+}
diff --git a/usr/src/usr.bin/eqn/font.c b/usr/src/usr.bin/eqn/font.c
new file mode 100644 (file)
index 0000000..3ef0e85
--- /dev/null
@@ -0,0 +1,59 @@
+# include "e.h"
+
+setfont(ch1) char ch1; {
+       /* use number '1', '2', '3' for roman, italic, bold */
+       yyval = ft;
+       if (ch1 == 'r' || ch1 == 'R')
+               ft = ROM;
+       else if (ch1 == 'i' || ch1 == 'I')
+               ft = ITAL;
+       else if (ch1 == 'b' || ch1 == 'B')
+               ft = BLD;
+       else
+               ft = ch1;
+       printf(".ft %c\n", ft);
+       if(dbg)printf(".\tsetfont %c %c\n", ch1, ft);
+}
+
+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);
+}
+
+globfont() {
+       char temp[20];
+
+       getstr(temp, 20);
+       yyval = eqnreg = 0;
+       gfont = temp[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;
+}
diff --git a/usr/src/usr.bin/eqn/fromto.c b/usr/src/usr.bin/eqn/fromto.c
new file mode 100644 (file)
index 0000000..d973b15
--- /dev/null
@@ -0,0 +1,45 @@
+# include "e.h"
+
+fromto(p1, p2, p3) int p1, p2, p3; {
+       int b, h1, b1, pss;
+       yyval = oalloc();
+       lfont[yyval] = rfont[yyval] = 0;
+       h1 = eht[yyval] = eht[p1];
+       b1 = ebase[p1];
+       b = 0;
+       pss = EFFPS(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, EFFPS(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, EFFPS(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);
+}
diff --git a/usr/src/usr.bin/eqn/funny.c b/usr/src/usr.bin/eqn/funny.c
new file mode 100644 (file)
index 0000000..a041d14
--- /dev/null
@@ -0,0 +1,26 @@
+# include "e.h"
+# include "e.def"
+
+funny(n) int n; {
+       char *f;
+
+       yyval = oalloc();
+       switch(n) {
+       case SUM:
+               f = "\\(*S"; break;
+       case UNION:
+               f = "\\(cu"; break;
+       case INTER:     /* intersection */
+               f = "\\(ca"; break;
+       case PROD:
+               f = "\\(*P"; break;
+       default:
+               error(FATAL, "funny type %d in funny", n);
+       }
+       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;
+}
diff --git a/usr/src/usr.bin/eqn/glob.c b/usr/src/usr.bin/eqn/glob.c
new file mode 100644 (file)
index 0000000..834a33f
--- /dev/null
@@ -0,0 +1,27 @@
+#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;   /* default initial point size */
+int    gfont   = ITAL; /* 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    eqnreg; /* register where final string appears */
+int    eqnht;  /* inal height of equation */
+int    lefteq  = '\0'; /* left in-line delimiter */
+int    righteq = '\0'; /* right in-line delimiter */
+int    lastchar;       /* last character read by lex */
+int    markline        = 0;    /* 1 if this EQ/EN contains mark or lineup */
diff --git a/usr/src/usr.bin/eqn/integral.c b/usr/src/usr.bin/eqn/integral.c
new file mode 100644 (file)
index 0000000..6e4bcb7
--- /dev/null
@@ -0,0 +1,30 @@
+# include "e.h"
+# include "e.def"
+
+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, SUB, p1);
+       else if (p2 != 0)
+               bshiftb(p, SUP, p2);
+       if(dbg)printf(".\tintegral: S%d; h=%d b=%d\n", 
+               p, eht[p], ebase[p]);
+       lfont[p] = ROM;
+}
+
+setintegral() {
+       char *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;
+}
diff --git a/usr/src/usr.bin/eqn/io.c b/usr/src/usr.bin/eqn/io.c
new file mode 100644 (file)
index 0000000..776bac7
--- /dev/null
@@ -0,0 +1,195 @@
+# include "e.h"
+#define        MAXLINE 1200    /* 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;
+
+       setfile(argc,argv);
+       init_tbl();     /* install keywords in tables */
+       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");
+                       markline = 0;
+                       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(".nr MK %d\n", markline);        /* for -ms macros */
+                               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) register char *s; {
+       register 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 ds;
+
+       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 (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\\s\\n(99\\f\\n(98",
+               gfont, gsize, p1, rfont[p1] == ITAL ? "\\|" : "");
+       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);
+       return(0);
+}
+
+ofree(n) int n; {
+       used[n] = 0;
+}
+
+setps(p) int p; {
+       printf(".ps %d\n", EFFPS(p));
+}
+
+nrwid(n1, p, n2) int n1, p, n2; {
+       printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, EFFPS(p), n2);
+}
+
+setfile(argc, argv) int argc; char *argv[]; {
+       static char *nullstr = "-";
+
+       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 = atoi(&svargv[1][2]); break;
+               case 'p': deltaps = atoi(&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;
+               svargv[1] = nullstr;
+       }
+       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);
+}
diff --git a/usr/src/usr.bin/eqn/lex.c b/usr/src/usr.bin/eqn/lex.c
new file mode 100644 (file)
index 0000000..19860a2
--- /dev/null
@@ -0,0 +1,211 @@
+#include "e.h"
+#include "e.def"
+
+#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", svargv[ifile]);
+       return(EOF);
+}
+
+pbstr(str)
+register char *str;
+{
+       register char *p;
+
+       p = str;
+       while (*p++);
+       --p;
+       if (ip >= &ibuf[PUSHBACK])
+               error( FATAL, "pushback overflow");
+       while (p > str)
+               putbak(*--p);
+}
+
+yylex() {
+       register int c;
+       tbl *tp, *lookup();
+       extern tbl **keytbl, **deftbl;
+
+  beg:
+       while ((c=gtc())==' ' || c=='\n')
+               ;
+       yylval=c;
+       switch(c) {
+
+       case EOF:
+               return(EOF);
+       case '~':
+               return(SPACE);
+       case '^':
+               return(THIN);
+       case '\t':
+               return(TAB);
+       case '{':
+               return('{');
+       case '}':
+               return('}');
+       case '"':
+               for (sp=0; (c=gtc())!='"' && c != '\n'; ) {
+                       if (c == '\\')
+                               if ((c = gtc()) != '"')
+                                       token[sp++] = '\\';
+                       token[sp++] = c;
+                       if (sp>=SSIZE)
+                               error(FATAL, "quoted string %.20s... too long", token);
+               }
+               token[sp]='\0';
+               yylval = (int) &token[0];
+               if (c == '\n')
+                       error(!FATAL, "missing \" in %.20s", token);
+               return(QTEXT);
+       }
+       if (c==righteq)
+               return(EOF);
+
+       putbak(c);
+       getstr(token, SSIZE);
+       if (dbg)printf(".\tlex token = |%s|\n", token);
+       if ((tp = lookup(&deftbl, token, NULL)) != NULL) {
+               putbak(' ');
+               pbstr(tp->defn);
+               putbak(' ');
+               if (dbg)
+                       printf(".\tfound %s|=%s|\n", token, tp->defn);
+       }
+       else if ((tp = lookup(&keytbl, token, NULL)) == NULL) {
+               if(dbg)printf(".\t%s is not a keyword\n", token);
+               return(CONTIG);
+       }
+       else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE)
+               define(tp->defn);
+       else if (tp->defn == (char *) DELIM)
+               delim();
+       else if (tp->defn == (char *) GSIZE)
+               globsize();
+       else if (tp->defn == (char *) GFONT)
+               globfont();
+       else if (tp->defn == (char *) INCLUDE)
+               include();
+       else {
+               return((int) tp->defn);
+       }
+       goto beg;
+}
+
+getstr(s, n) char *s; register int n; {
+       register int c;
+       register char *p;
+
+       p = s;
+       while ((c = gtc()) == ' ' || c == '\n')
+               ;
+       if (c == EOF) {
+               *s = 0;
+               return;
+       }
+       while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
+         && c != '"' && c != '~' && c != '^' && c != righteq) {
+               if (c == '\\')
+                       if ((c = gtc()) != '"')
+                               *p++ = '\\';
+               *p++ = c;
+               if (--n <= 0)
+                       error(FATAL, "token %.20s... too long", s);
+               c = gtc();
+       }
+       if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
+               putbak(c);
+       *p = '\0';
+       yylval = (int) s;
+}
+
+cstr(s, quote, maxs) char *s; int quote; {
+       int del, c, i;
+
+       while((del=gtc()) == ' ' || del == '\t' || del == '\n');
+       if (quote)
+               for (i=0; (c=gtc()) != del && c != EOF;) {
+                       s[i++] = c;
+                       if (i >= maxs)
+                               return(1);      /* disaster */
+               }
+       else {
+               s[0] = del;
+               for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
+                       s[i++]=c;
+                       if (i >= maxs)
+                               return(1);      /* disaster */
+               }
+       }
+       s[i] = '\0';
+       if (c == EOF)
+               error(FATAL, "Unexpected end of input at %.20s", s);
+       return(0);
+}
+
+define(type) int type; {
+       char *strsave(), *p1, *p2;
+       tbl *lookup();
+       extern tbl **deftbl;
+
+       getstr(token, SSIZE);   /* get name */
+       if (type != DEFINE) {
+               cstr(token, 1, SSIZE);  /* skip the definition too */
+               return;
+       }
+       p1 = strsave(token);
+       if (cstr(token, 1, SSIZE))
+               error(FATAL, "Unterminated definition at %.20s", token);
+       p2 = strsave(token);
+       lookup(&deftbl, p1, p2);
+       if (dbg)printf(".\tname %s defined as %s\n", p1, p2);
+}
+
+char *strsave(s)
+char *s;
+{
+       char *malloc();
+       register char *q;
+
+       q = malloc(strlen(s)+1);
+       if (q == NULL)
+               error(FATAL, "out of space in strsave on %s", s);
+       strcpy(q, s);
+       return(q);
+}
+
+include() {
+       error(!FATAL, "Include not yet implemented");
+}
+
+delim() {
+       yyval = eqnreg = 0;
+       if (cstr(token, 0, SSIZE))
+               error(FATAL, "Bizarre delimiters at %.20s", token);
+       lefteq = token[0];
+       righteq = token[1];
+       if (lefteq == 'o' && righteq == 'f')
+               lefteq = righteq = '\0';
+}
diff --git a/usr/src/usr.bin/eqn/lookup.c b/usr/src/usr.bin/eqn/lookup.c
new file mode 100644 (file)
index 0000000..55a1e1a
--- /dev/null
@@ -0,0 +1,224 @@
+# include "e.h"
+#include "e.def"
+
+#define        TBLSIZE 100
+
+tbl    *keytbl[TBLSIZE];       /* key words */
+tbl    *restbl[TBLSIZE];       /* reserved words */
+tbl    *deftbl[TBLSIZE];       /* user-defined names */
+
+struct {
+       char    *key;
+       int     keyval;
+} keyword[]    ={
+       "sub",  SUB, 
+       "sup",  SUP, 
+       ".EN",  EOF, 
+       "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, 
+
+#ifdef NEQN    /* make ndefine synonym for define, tdefine a no-op */
+
+       "tdefine",      TDEFINE,
+       "ndefine",      DEFINE,
+
+#else          /* tdefine = define, ndefine = no-op */
+
+       "tdefine",      DEFINE, 
+       "ndefine",      NDEFINE, 
+
+#endif
+
+       "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
+};
+
+struct {
+       char    *res;
+       char    *resval;
+} resword[]    ={
+       ">=",   "\\(>=",
+       "<=",   "\\(<=",
+       "==",   "\\(==",
+       "!=",   "\\(!=",
+       "+-",   "\\(+-",
+       "->",   "\\(->",
+       "<-",   "\\(<-",
+       "inf",  "\\(if",
+       "infinity",     "\\(if",
+       "partial",      "\\(pd",
+       "half", "\\f1\\(12\\fP",
+       "prime",        "\\f1\\(fm\\fP",
+       "dollar",       "\\f1$\\fP",
+       "nothing",      "",
+       "times",        "\\(mu",
+       "del",  "\\(gr",
+       "grad", "\\(gr",
+#ifdef NEQN
+       "<<",   "<<",
+       ">>",   ">>",
+       "approx",       "~\b\\d~\\u",
+       "cdot", "\\v'-.5'.\\v'.5'",
+       "...",  "...",
+       ",...,",        ",...,",
+#else
+       "<<",   "<\\h'-.3m'<",
+       ">>",   ">\\h'-.3m'>",
+       "approx",       "\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'",
+       "cdot", "\\v'-.3m'.\\v'.3m'",
+       "...",  "\\v'-.3m'\\ .\\ .\\ .\\ \\v'.3m'",
+       ",...,",        ",\\ .\\ .\\ .\\ ,\\|",
+#endif
+
+       "alpha",        "\\(*a",
+       "beta", "\\(*b",
+       "gamma",        "\\(*g",
+       "GAMMA",        "\\(*G",
+       "delta",        "\\(*d",
+       "DELTA",        "\\(*D",
+       "epsilon",      "\\(*e",
+       "EPSILON",      "\\f1E\\fP",
+       "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",  "\\f1and\\fP",
+       "for",  "\\f1for\\fP",
+       "if",   "\\f1if\\fP",
+       "Re",   "\\f1Re\\fP",
+       "Im",   "\\f1Im\\fP",
+       "sin",  "\\f1sin\\fP",
+       "cos",  "\\f1cos\\fP",
+       "tan",  "\\f1tan\\fP",
+       "sec",  "\\f1sec\\fP",
+       "csc",  "\\f1csc\\fP",
+       "arc",  "\\f1arc\\fP",
+       "asin", "\\f1asin\\fP",
+       "acos", "\\f1acos\\fP",
+       "atan", "\\f1atan\\fP",
+       "asec", "\\f1asec\\fP",
+       "acsc", "\\f1acsc\\fP",
+       "sinh", "\\f1sinh\\fP",
+       "coth", "\\f1coth\\fP",
+       "tanh", "\\f1tanh\\fP",
+       "cosh", "\\f1cosh\\fP",
+       "lim",  "\\f1lim\\fP",
+       "log",  "\\f1log\\fP",
+       "max",  "\\f1max\\fP",
+       "min",  "\\f1min\\fP",
+       "ln",   "\\f1ln\\fP",
+       "exp",  "\\f1exp\\fP",
+       "det",  "\\f1det\\fP",
+       0,      0
+};
+
+tbl *lookup(tblp, name, defn)  /* find name in tbl. if defn non-null, install */
+tbl **tblp;
+char *name, *defn;
+{
+       register tbl *p;
+       register int h;
+       register char *s = name;
+       char *malloc();
+
+       for (h = 0; *s != '\0'; )
+               h += *s++;
+       h %= TBLSIZE;
+
+       for (p = tblp[h]; p != NULL; p = p->next)
+               if (strcmp(name, p->name) == 0) {       /* found it */
+                       if (defn != NULL)
+                               p->defn = defn;
+                       return(p);
+               }
+       /* didn't find it */
+       if (defn == NULL)
+               return(NULL);
+       p = (tbl *) malloc(sizeof (tbl));
+       if (p == NULL)
+               error(FATAL, "out of space in lookup");
+       p->name = name;
+       p->defn = defn;
+       p->next = tblp[h];
+       tblp[h] = p;
+       return(p);
+}
+
+init_tbl()     /* initialize all tables */
+{
+       int i;
+
+       for (i = 0; keyword[i].key != NULL; i++)
+               lookup(keytbl, keyword[i].key, keyword[i].keyval);
+       for (i = 0; resword[i].res != NULL; i++)
+               lookup(restbl, resword[i].res, resword[i].resval);
+}
diff --git a/usr/src/usr.bin/eqn/lookup.old.c b/usr/src/usr.bin/eqn/lookup.old.c
new file mode 100644 (file)
index 0000000..aa6ea92
--- /dev/null
@@ -0,0 +1,217 @@
+# include "e.h"
+#include "e.def"
+
+#define        TBLSIZE 100
+
+tbl    *keytbl[TBLSIZE];       /* key words */
+tbl    *restbl[TBLSIZE];       /* reserved words */
+tbl    *deftbl[TBLSIZE];       /* user-defined names */
+
+struct {
+       char    *key;
+       int     keyval;
+} keyword[]    ={
+       "sub",  SUB, 
+       "sup",  SUP, 
+       ".EN",  EOF, 
+       "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, 
+
+#ifdef NEQN    /* make ndefine synonym for define, tdefine a no-op */
+
+       "tdefine",      TDEFINE,
+       "ndefine",      DEFINE,
+
+#else          /* tdefine = define, ndefine = no-op */
+
+       "tdefine",      DEFINE, 
+       "ndefine",      NDEFINE, 
+
+#endif
+
+       "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
+};
+
+struct {
+       char    *res;
+       char    *resval;
+} resword[]    ={
+       ">=",   "\\(>=",
+       "<=",   "\\(<=",
+       "==",   "\\(==",
+       "!=",   "\\(!=",
+       "+-",   "\\(+-",
+       "->",   "\\(->",
+       "<-",   "\\(<-",
+       "inf",  "\\(if",
+       "infinity",     "\\(if",
+       "partial",      "\\(pd",
+       "half", "\\f1\\(12\\fP",
+       "prime",        "\\f1\\(fm\\fP",
+       "dollar",       "\\f1$\\fP",
+       "nothing",      "",
+       "times",        "\\(mu",
+       "del",  "\\(gr",
+       "grad", "\\(gr",
+#ifdef NEQN
+       "<<",   "<<",
+       ">>",   ">>",
+       "approx",       "~\b\\d~\\u",
+       "cdot", "\\v'-.5'.\\v'.5'",
+       "...",  "...",
+       ",...,",        ",...,",
+#else
+       "<<",   "<\\h'-.3m'<",
+       ">>",   ">\\h'-.3m'>",
+       "approx",       "\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'",
+       "cdot", "\\v'-.3m'.\\v'.3m'",
+       "...",  "\\v'-.3m'\\ .\\ .\\ .\\ \\v'.3m'",
+       ",...,",        ",\\ .\\ .\\ .\\ ,\\|",
+#endif
+
+       "alpha",        "\\(*a",
+       "beta", "\\(*b",
+       "gamma",        "\\(*g",
+       "GAMMA",        "\\(*G",
+       "delta",        "\\(*d",
+       "DELTA",        "\\(*D",
+       "epsilon",      "\\(*e",
+       "EPSILON",      "\\f1E\\fP",
+       "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",  "\\f1and\\fP",
+       "for",  "\\f1for\\fP",
+       "if",   "\\f1if\\fP",
+       "Re",   "\\f1Re\\fP",
+       "Im",   "\\f1Im\\fP",
+       "sin",  "\\f1sin\\fP",
+       "cos",  "\\f1cos\\fP",
+       "tan",  "\\f1tan\\fP",
+       "arc",  "\\f1arc\\fP",
+       "sinh", "\\f1sinh\\fP",
+       "coth", "\\f1coth\\fP",
+       "tanh", "\\f1tanh\\fP",
+       "cosh", "\\f1cosh\\fP",
+       "lim",  "\\f1lim\\fP",
+       "log",  "\\f1log\\fP",
+       "max",  "\\f1max\\fP",
+       "min",  "\\f1min\\fP",
+       "ln",   "\\f1ln\\fP",
+       "exp",  "\\f1exp\\fP",
+       "det",  "\\f1det\\fP",
+       0,      0
+};
+
+tbl *lookup(tblp, name, defn)  /* find name in tbl. if defn non-null, install */
+tbl **tblp;
+char *name, *defn;
+{
+       register tbl *p;
+       register int h;
+       register char *s = name;
+       char *malloc();
+
+       for (h = 0; *s != '\0'; )
+               h += *s++;
+       h %= TBLSIZE;
+
+       for (p = tblp[h]; p != NULL; p = p->next)
+               if (strcmp(name, p->name) == 0) {       /* found it */
+                       if (defn != NULL)
+                               p->defn = defn;
+                       return(p);
+               }
+       /* didn't find it */
+       if (defn == NULL)
+               return(NULL);
+       p = (tbl *) malloc(sizeof (tbl));
+       if (p == NULL)
+               error(FATAL, "out of space in lookup");
+       p->name = name;
+       p->defn = defn;
+       p->next = tblp[h];
+       tblp[h] = p;
+       return(p);
+}
+
+init_tbl()     /* initialize all tables */
+{
+       int i;
+
+       for (i = 0; keyword[i].key != NULL; i++)
+               lookup(keytbl, keyword[i].key, keyword[i].keyval);
+       for (i = 0; resword[i].res != NULL; i++)
+               lookup(restbl, resword[i].res, resword[i].resval);
+}
diff --git a/usr/src/usr.bin/eqn/mark.c b/usr/src/usr.bin/eqn/mark.c
new file mode 100644 (file)
index 0000000..6e03156
--- /dev/null
@@ -0,0 +1,17 @@
+#include "e.h"
+
+mark(p1) int p1; {
+       markline = 1;
+       printf(".ds %d \\k(97\\*(%d\n", p1, p1);
+       yyval = p1;
+       if(dbg)printf(".\tmark %d\n", p1);
+}
+
+lineup(p1) {
+       markline = 1;
+       if (p1 == 0) {
+               yyval = oalloc();
+               printf(".ds %d \\h'|\\n(97u'\n", yyval);
+       }
+       if(dbg)printf(".\tlineup %d\n", p1);
+}
diff --git a/usr/src/usr.bin/eqn/matrix.c b/usr/src/usr.bin/eqn/matrix.c
new file mode 100644 (file)
index 0000000..209e37b
--- /dev/null
@@ -0,0 +1,62 @@
+#include "e.h"
+
+column(type, p1) int type, p1; {
+       int i;
+
+       lp[p1] = ct - p1 - 1;
+       if( dbg ){
+               printf(".\t%d 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) int p1; {
+       int nrow, ncol, i, j, k, hb, b, val[100];
+       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;
+}
diff --git a/usr/src/usr.bin/eqn/move.c b/usr/src/usr.bin/eqn/move.c
new file mode 100644 (file)
index 0000000..c4d30fa
--- /dev/null
@@ -0,0 +1,18 @@
+# include "e.h"
+# include "e.def"
+
+move(dir, amt, p) int dir, amt, p; {
+       int a;
+
+       yyval = p;
+       a = VERT( (EFFPS(ps) * 6 * amt) / 100);
+       printf(".ds %d ", yyval);
+       if( dir == FWD || dir == BACK ) /* fwd, back */
+               printf("\\h'%s%du'\\*(%d\n", (dir==BACK) ? "-" : "", a, p);
+       else if (dir == UP)
+               printf("\\v'-%du'\\*(%d\\v'%du'\n", a, p, a);
+       else if (dir == DOWN)
+               printf("\\v'%du'\\*(%d\\v'-%du'\n", a, p, a);
+       if(dbg)printf(".\tmove %d dir %d amt %d; h=%d b=%d\n", 
+               p, dir, a, eht[yyval], ebase[yyval]);
+}
diff --git a/usr/src/usr.bin/eqn/over.c b/usr/src/usr.bin/eqn/over.c
new file mode 100644 (file)
index 0000000..feadac3
--- /dev/null
@@ -0,0 +1,29 @@
+# include "e.h"
+
+boverb(p1, p2) int p1, p2; {
+       int h, b, treg, d;
+
+       treg = oalloc();
+       yyval = p1;
+       d = VERT((ps*6*3) / 10);        /* 0.3m */
+       h = eht[p1] + eht[p2] + 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, EFFPS(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);
+}
diff --git a/usr/src/usr.bin/eqn/paren.c b/usr/src/usr.bin/eqn/paren.c
new file mode 100644 (file)
index 0000000..f789581
--- /dev/null
@@ -0,0 +1,105 @@
+# include "e.h"
+
+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*EFFPS(ps)-1))/(6*EFFPS(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, (char *) &leftc, (char *) &leftc, (char *) &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, (char *) &rightc, (char *) &rightc, (char *) &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);
+}
diff --git a/usr/src/usr.bin/eqn/pile.c b/usr/src/usr.bin/eqn/pile.c
new file mode 100644 (file)
index 0000000..c2873d2
--- /dev/null
@@ -0,0 +1,62 @@
+# include "e.h"
+
+lpile(type, p1, p2) int type, p1, p2; {
+       int bi, hi, i, gap, h, b, 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=='R' ? 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 'R':
+               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!='R' ? 1 : 0, yyval);
+       for( i=p1; i<p2; i++ )
+               ofree(lp[i]);
+       lfont[yyval] = rfont[yyval] = 0;
+}
diff --git a/usr/src/usr.bin/eqn/shift.c b/usr/src/usr.bin/eqn/shift.c
new file mode 100644 (file)
index 0000000..adc7664
--- /dev/null
@@ -0,0 +1,103 @@
+# include "e.h"
+#include "e.def"
+
+bshiftb(p1, dir, p2) int p1, dir, p2; {
+       int shval, diffps, effps, effps2, d1, h1, b1, h2, b2;
+       char *sh1, *sh2;
+
+       yyval = p1;
+       h1 = eht[p1];
+       b1 = ebase[p1];
+       h2 = eht[p2];
+       b2 = ebase[p2];
+       effps = EFFPS(ps);
+       effps2 = EFFPS(ps+deltaps);
+       diffps = deltaps;
+       sh1 = sh2 = "";
+       if( dir == SUB ) {
+               /* 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 (rfont[p2] == ITAL)
+                       sh2 = "\\|";
+       }
+       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+%d%s\\v'%du'\n", 
+               yyval, shval, diffps, sh1, p2, diffps, sh2, -shval);
+       ps += deltaps;
+       if (rfont[p2] == ITAL)
+               rfont[p1] = 0;
+       else
+               rfont[p1] = rfont[p2];
+       ofree(p2);
+}
+
+shift(p1) int p1; {
+       ps -= deltaps;
+       yyval = p1;
+       if(dbg)printf(".\tshift: %d;ps=%d\n", yyval, ps);
+}
+
+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 = EFFPS(ps+deltaps);
+       eht[p3] = h3 = VERT( (eht[p3] * effps) / EFFPS(ps) );
+       ps += deltaps;
+       effps2 = EFFPS(ps+deltaps);
+       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);
+}
diff --git a/usr/src/usr.bin/eqn/size.c b/usr/src/usr.bin/eqn/size.c
new file mode 100644 (file)
index 0000000..8f99fa6
--- /dev/null
@@ -0,0 +1,46 @@
+# include "e.h"
+
+setsize(p)     /* set size as found in p */
+char *p;
+{
+       if (*p == '+')
+               ps += atoi(p+1);
+       else if (*p == '-')
+               ps -= atoi(p+1);
+       else
+               ps = atoi(p);
+       if(dbg)printf(".\tsetsize %s; ps = %d\n", p, ps);
+}
+
+size(p1, p2) int p1, p2; {
+               /* old size in p1, new in ps */
+       int effps, effp1;
+
+       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]);
+       effps = EFFPS(ps);
+       effp1 = EFFPS(p1);
+       printf(".ds %d \\s%d\\*(%d\\s%d\n", 
+               yyval, effps, p2, effp1);
+       ps = p1;
+}
+
+globsize() {
+       char temp[20];
+
+       getstr(temp, 20);
+       if (temp[0] == '+')
+               gsize += atoi(temp+1);
+       else if (temp[0] == '-')
+               gsize -= atoi(temp+1);
+       else
+               gsize = atoi(temp);
+       yyval = eqnreg = 0;
+       setps(gsize);
+       ps = gsize;
+       if (gsize >= 12)        /* sub and sup size change */
+               deltaps = gsize / 4;
+       else
+               deltaps = gsize / 3;
+}
diff --git a/usr/src/usr.bin/eqn/sqrt.c b/usr/src/usr.bin/eqn/sqrt.c
new file mode 100644 (file)
index 0000000..2229328
--- /dev/null
@@ -0,0 +1,17 @@
+# include "e.h"
+
+sqrt(p2) int p2; {
+       int nps;
+       nps = EFFPS(((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);
+       lfont[yyval] = ROM;
+}
diff --git a/usr/src/usr.bin/eqn/text.c b/usr/src/usr.bin/eqn/text.c
new file mode 100644 (file)
index 0000000..79289d0
--- /dev/null
@@ -0,0 +1,170 @@
+# include "e.h"
+# include "e.def"
+
+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 c;
+       char *p;
+       tbl *tp, *lookup();
+       extern tbl *restbl;
+
+       yyval = oalloc();
+       ebase[yyval] = 0;
+       eht[yyval] = VERT(6 * ((ps>6)?ps:6));   /* ht in machine units */
+       lfont[yyval] = rfont[yyval] = ROM;
+       if (t == QTEXT)
+               p = p1;
+       else if ( t == SPACE )
+               p = "\\ ";
+       else if ( t == THIN )
+               p = "\\|";
+       else if ( t == TAB )
+               p = "\\t";
+       else if ((tp = lookup(&restbl, p1, NULL)) != NULL)
+               p = tp->defn;
+       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';
+               p = cs;
+               lfont[yyval] = lf;
+               rfont[yyval] = rf;
+       }
+       if(dbg)printf(".\t%dtext: S%d <- %s; b=%d,h=%d,lf=%c,rf=%c\n",
+               t, yyval, p, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]);
+       printf(".ds %d \"%s\n", yyval, p);
+}
+
+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 ']':
+       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++] = '|';      /* trying | instead of ^ */
+                       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;
+}