From 44df7640cb76952179f06cb82235c6ffae7b0dfc Mon Sep 17 00:00:00 2001 From: "Brian W. Kernighan" Date: Wed, 10 Jan 1979 15:03:31 -0500 Subject: [PATCH] Research V7 development Work on file usr/src/cmd/neqn/diacrit.c Work on file usr/src/cmd/neqn/eqnbox.c Work on file usr/src/cmd/neqn/e.h Work on file usr/src/cmd/neqn/e.y Work on file usr/src/cmd/neqn/font.c Work on file usr/src/cmd/neqn/glob.c Work on file usr/src/cmd/neqn/fromto.c Work on file usr/src/cmd/neqn/funny.c Work on file usr/src/cmd/neqn/io.c Work on file usr/src/cmd/neqn/integral.c Work on file usr/src/cmd/neqn/lex.c Work on file usr/src/cmd/neqn/lookup.c Work on file usr/src/cmd/neqn/makefile Work on file usr/src/cmd/neqn/matrix.c Work on file usr/src/cmd/neqn/move.c Work on file usr/src/cmd/neqn/mark.c Work on file usr/src/cmd/neqn/paren.c Work on file usr/src/cmd/neqn/over.c Work on file usr/src/cmd/neqn/pile.c Work on file usr/src/cmd/neqn/shift.c Work on file usr/src/cmd/neqn/sqrt.c Work on file usr/src/cmd/neqn/size.c Work on file usr/src/cmd/neqn/text.c Co-Authored-By: Lorinda Cherry Synthesized-from: v7 --- usr/src/cmd/neqn/diacrit.c | 44 ++++++++ usr/src/cmd/neqn/e.h | 42 +++++++ usr/src/cmd/neqn/e.y | 166 +++++++++++++++++++++++++++ usr/src/cmd/neqn/eqnbox.c | 25 +++++ usr/src/cmd/neqn/font.c | 59 ++++++++++ usr/src/cmd/neqn/fromto.c | 45 ++++++++ usr/src/cmd/neqn/funny.c | 26 +++++ usr/src/cmd/neqn/glob.c | 27 +++++ usr/src/cmd/neqn/integral.c | 31 ++++++ usr/src/cmd/neqn/io.c | 195 ++++++++++++++++++++++++++++++++ usr/src/cmd/neqn/lex.c | 211 +++++++++++++++++++++++++++++++++++ usr/src/cmd/neqn/lookup.c | 217 ++++++++++++++++++++++++++++++++++++ usr/src/cmd/neqn/makefile | 45 ++++++++ usr/src/cmd/neqn/mark.c | 17 +++ usr/src/cmd/neqn/matrix.c | 62 +++++++++++ usr/src/cmd/neqn/move.c | 18 +++ usr/src/cmd/neqn/over.c | 28 +++++ usr/src/cmd/neqn/paren.c | 106 ++++++++++++++++++ usr/src/cmd/neqn/pile.c | 62 +++++++++++ usr/src/cmd/neqn/shift.c | 70 ++++++++++++ usr/src/cmd/neqn/size.c | 46 ++++++++ usr/src/cmd/neqn/sqrt.c | 12 ++ usr/src/cmd/neqn/text.c | 170 ++++++++++++++++++++++++++++ 23 files changed, 1724 insertions(+) create mode 100644 usr/src/cmd/neqn/diacrit.c create mode 100644 usr/src/cmd/neqn/e.h create mode 100644 usr/src/cmd/neqn/e.y create mode 100644 usr/src/cmd/neqn/eqnbox.c create mode 100644 usr/src/cmd/neqn/font.c create mode 100644 usr/src/cmd/neqn/fromto.c create mode 100644 usr/src/cmd/neqn/funny.c create mode 100644 usr/src/cmd/neqn/glob.c create mode 100644 usr/src/cmd/neqn/integral.c create mode 100644 usr/src/cmd/neqn/io.c create mode 100644 usr/src/cmd/neqn/lex.c create mode 100644 usr/src/cmd/neqn/lookup.c create mode 100644 usr/src/cmd/neqn/makefile create mode 100644 usr/src/cmd/neqn/mark.c create mode 100644 usr/src/cmd/neqn/matrix.c create mode 100644 usr/src/cmd/neqn/move.c create mode 100644 usr/src/cmd/neqn/over.c create mode 100644 usr/src/cmd/neqn/paren.c create mode 100644 usr/src/cmd/neqn/pile.c create mode 100644 usr/src/cmd/neqn/shift.c create mode 100644 usr/src/cmd/neqn/size.c create mode 100644 usr/src/cmd/neqn/sqrt.c create mode 100644 usr/src/cmd/neqn/text.c diff --git a/usr/src/cmd/neqn/diacrit.c b/usr/src/cmd/neqn/diacrit.c new file mode 100644 index 0000000000..d38d24db38 --- /dev/null +++ b/usr/src/cmd/neqn/diacrit.c @@ -0,0 +1,44 @@ +# include "e.h" +# include "e.def" + +diacrit(p1, type) int p1, type; { + int c, t; + + c = oalloc(); + t = oalloc(); + nrwid(p1, ps, p1); + printf(".nr 10 %du\n", max(eht[p1]-ebase[p1]-VERT(2),0)); + switch(type) { + case VEC: /* vec */ + case DYAD: /* dyad */ + printf(".ds %d \\v'-1'_\\v'1'\n", c); + break; + case HAT: + printf(".ds %d ^\n", c); + break; + case TILDE: + printf(".ds %d ~\n", c); + break; + case DOT: + printf(".ds %d \\v'-1'.\\v'1'\n", c); + break; + case DOTDOT: + printf(".ds %d \\v'-1'..\\v'1'\n", c); + break; + case BAR: + printf(".ds %d \\v'-1'\\l'\\n(%du'\\v'1'\n", + c, p1); + break; + case UNDER: + printf(".ds %d \\l'\\n(%du'\n", c, p1); + break; + } + nrwid(c, ps, c); + printf(".as %d \\h'-\\n(%du-\\n(%du/2u'\\v'0-\\n(10u'\\*(%d", + p1, p1, c, c); + printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u'\n", c, p1); + if (type != UNDER) + eht[p1] += VERT(1); + if (dbg) printf(".\tdiacrit: %c over S%d, h=%d, b=%d\n", type, p1, eht[p1], ebase[p1]); + ofree(c); ofree(t); +} diff --git a/usr/src/cmd/neqn/e.h b/usr/src/cmd/neqn/e.h new file mode 100644 index 0000000000..4722f6b4f2 --- /dev/null +++ b/usr/src/cmd/neqn/e.h @@ -0,0 +1,42 @@ +#include + +#define FATAL 1 +#define ROM '1' +#define ITAL '1' +#define BLD '1' + +#define VERT(n) (20 * (n)) +#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/cmd/neqn/e.y b/usr/src/cmd/neqn/e.y new file mode 100644 index 0000000000..f294e59738 --- /dev/null +++ b/usr/src/cmd/neqn/e.y @@ -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/cmd/neqn/eqnbox.c b/usr/src/cmd/neqn/eqnbox.c new file mode 100644 index 0000000000..2aea8da378 --- /dev/null +++ b/usr/src/cmd/neqn/eqnbox.c @@ -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/cmd/neqn/font.c b/usr/src/cmd/neqn/font.c new file mode 100644 index 0000000000..e4e026e6be --- /dev/null +++ b/usr/src/cmd/neqn/font.c @@ -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\n", 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/cmd/neqn/fromto.c b/usr/src/cmd/neqn/fromto.c new file mode 100644 index 0000000000..d792d1e70d --- /dev/null +++ b/usr/src/cmd/neqn/fromto.c @@ -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/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/cmd/neqn/funny.c b/usr/src/cmd/neqn/funny.c new file mode 100644 index 0000000000..1b93818e89 --- /dev/null +++ b/usr/src/cmd/neqn/funny.c @@ -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\n", yyval, f); + eht[yyval] = VERT(2); + ebase[yyval] = 0; + 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/cmd/neqn/glob.c b/usr/src/cmd/neqn/glob.c new file mode 100644 index 0000000000..834a33f4f6 --- /dev/null +++ b/usr/src/cmd/neqn/glob.c @@ -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/cmd/neqn/integral.c b/usr/src/cmd/neqn/integral.c new file mode 100644 index 0000000000..1247250709 --- /dev/null +++ b/usr/src/cmd/neqn/integral.c @@ -0,0 +1,31 @@ +# include "e.h" +# include "e.def" + +integral(p, p1, p2) { +#ifndef NEQN + 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); +#endif + 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\n", yyval, f); + eht[yyval] = VERT(2); + ebase[yyval] = 0; + lfont[yyval] = rfont[yyval] = ROM; +} diff --git a/usr/src/cmd/neqn/io.c b/usr/src/cmd/neqn/io.c new file mode 100644 index 0000000000..541d31dd60 --- /dev/null +++ b/usr/src/cmd/neqn/io.c @@ -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(3); /* 3 = 1.5 lines */ + 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(1); + 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/cmd/neqn/lex.c b/usr/src/cmd/neqn/lex.c new file mode 100644 index 0000000000..19860a2307 --- /dev/null +++ b/usr/src/cmd/neqn/lex.c @@ -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/cmd/neqn/lookup.c b/usr/src/cmd/neqn/lookup.c new file mode 100644 index 0000000000..aa6ea9279b --- /dev/null +++ b/usr/src/cmd/neqn/lookup.c @@ -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/cmd/neqn/makefile b/usr/src/cmd/neqn/makefile new file mode 100644 index 0000000000..1fe54e60b2 --- /dev/null +++ b/usr/src/cmd/neqn/makefile @@ -0,0 +1,45 @@ +CFLAGS=-O -s -DNEQN +YFLAGS=-d + +all: neqn + +cp: neqn + cp neqn /bin/neqn + rm *.o e.c e.def neqn + +cmp: neqn + cmp neqn /bin/neqn + rm *.o e.c e.def neqn + +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 + +neqn: $(FILES) + cc -n $(CFLAGS) $(FILES) -o neqn + +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 + +list: + pr TODO $(SOURCE) makefile + +gcos: y.tab.c + fsend e.h e.y *.c + +src: makefile $(SOURCE) + cp $? /usr/src/cmd/neqn + touch src + +lint: y.tab.c + lint -spb *.c diff --git a/usr/src/cmd/neqn/mark.c b/usr/src/cmd/neqn/mark.c new file mode 100644 index 0000000000..6e03156bfa --- /dev/null +++ b/usr/src/cmd/neqn/mark.c @@ -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/cmd/neqn/matrix.c b/usr/src/cmd/neqn/matrix.c new file mode 100644 index 0000000000..209e37be71 --- /dev/null +++ b/usr/src/cmd/neqn/matrix.c @@ -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\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2); + 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]-ebase[p1], p1); + printf("\\h'-\\n(%du-\\n(%du-2u/2u'\\v'%du'\\l'\\n(%du'\\v'%du'\n", + treg, p1, ebase[p1], treg, d); + ebase[yyval] = b; + eht[yyval] = h; + lfont[yyval] = rfont[yyval] = 0; + ofree(p2); + ofree(treg); +} diff --git a/usr/src/cmd/neqn/paren.c b/usr/src/cmd/neqn/paren.c new file mode 100644 index 0000000000..58c91bb252 --- /dev/null +++ b/usr/src/cmd/neqn/paren.c @@ -0,0 +1,106 @@ +# 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; + n = max(b1+VERT(1), h1-b1-VERT(1)) / VERT(1); + 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(2 * n); + ebase[yyval] = (n)/2 * VERT(2); + if (n%2 == 0) + ebase[yyval] -= VERT(1); + v = b1 - h1/2 + VERT(1); + 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; jmid; i-- ) + b += eht[lp[i]] + gap; + ebase[yyval] = (nlist%2) ? b + ebase[lp[mid]] + : b - VERT(1) - gap; + if(dbg) { + printf(".\tS%d <- %c pile of:", yyval, type); + for( i=p1; i\\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 h2 ) /* move little sub down */ + shval = b1-b2; + ebase[yyval] = b1 + max(0, h2-b1-d1); + eht[yyval] = h1 + max(0, h2-b1-d1); + } else { /* superscript */ + d1 = VERT(1); + ebase[yyval] = b1; + shval = -VERT(1) - b2; + if( VERT(1) + h2 < h1-b1 ) /* raise little super */ + shval = -(h1-b1) + h2-b2 - d1; + eht[yyval] = h1 + max(0, h2 - VERT(1)); + } + 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'\\*(%d\\v'%du'\n", + yyval, shval, p2, -shval); + 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, 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); + h1 = eht[p1]; b1 = ebase[p1]; + h2 = eht[p2]; b2 = ebase[p2]; + h3 = eht[p3]; b3 = ebase[p3]; + d1 = VERT(1); + subsh = -d1+h2-b2; + if( d1+b1 > h2 ) /* move little sub down */ + subsh = b1-b2; + supsh = - VERT(1) - b3; + d2 = VERT(1); + if( VERT(1)+h3 < h1-b1 ) + supsh = -(h1-b1) + (h3-b3) - d2; + eht[yyval] = h1 + max(0, h3-VERT(1)) + max(0, h2-b1-d1); + ebase[yyval] = b1+max(0, h2-b1-d1); + nrwid(p2, effps, p2); + 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'\\*(%d\\h'-\\n(%du'\\v'%du'\\\n", + p1, subsh, p2, p2, -subsh+supsh); + printf("\\*(%d\\h'-\\n(%du+\\n(%du'\\v'%du'\n", + p3, p3, treg, -supsh); + ps += deltaps; + ofree(p2); ofree(p3); ofree(treg); +} diff --git a/usr/src/cmd/neqn/size.c b/usr/src/cmd/neqn/size.c new file mode 100644 index 0000000000..8f99fa6804 --- /dev/null +++ b/usr/src/cmd/neqn/size.c @@ -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/cmd/neqn/sqrt.c b/usr/src/cmd/neqn/sqrt.c new file mode 100644 index 0000000000..e236f0ea0c --- /dev/null +++ b/usr/src/cmd/neqn/sqrt.c @@ -0,0 +1,12 @@ +# include "e.h" + +sqrt(p2) int p2; { + yyval = p2; + nrwid(p2, ps, p2); + printf(".ds %d \\v'%du'\\e\\L'%du'\\l'\\n(%du'", + p2, ebase[p2], -eht[p2], p2); + printf("\\v'%du'\\h'-\\n(%du'\\*(%d\n", eht[p2]-ebase[p2], p2, p2); + eht[p2] =+ VERT(1); + if(dbg)printf(".\tsqrt: S%d <- S%d;b=%d, h=%d\n", + p2, p2, ebase[p2], eht[p2]); +} diff --git a/usr/src/cmd/neqn/text.c b/usr/src/cmd/neqn/text.c new file mode 100644 index 0000000000..0686dcac45 --- /dev/null +++ b/usr/src/cmd/neqn/text.c @@ -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(2); /* 2 half-spaces */ + 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; +} -- 2.20.1