From 5cedca1b69d020c32466f70843a11767773d7e3b Mon Sep 17 00:00:00 2001 From: rsc Date: Sat, 15 May 2004 23:24:00 +0000 Subject: Let's try this. It's BUGGERED. --- src/cmd/eqn/diacrit.c | 75 +++++ src/cmd/eqn/e.h | 166 +++++++++++ src/cmd/eqn/eqn.c | 741 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cmd/eqn/eqn.y | 140 +++++++++ src/cmd/eqn/eqnbox.c | 24 ++ src/cmd/eqn/font.c | 70 +++++ src/cmd/eqn/fromto.c | 52 ++++ src/cmd/eqn/funny.c | 30 ++ src/cmd/eqn/glob.c | 35 +++ src/cmd/eqn/input.c | 289 +++++++++++++++++++ src/cmd/eqn/integral.c | 30 ++ src/cmd/eqn/lex.c | 265 +++++++++++++++++ src/cmd/eqn/lookup.c | 219 ++++++++++++++ src/cmd/eqn/main.c | 333 ++++++++++++++++++++++ src/cmd/eqn/mark.c | 19 ++ src/cmd/eqn/matrix.c | 78 +++++ src/cmd/eqn/mkfile | 42 +++ src/cmd/eqn/move.c | 19 ++ src/cmd/eqn/o.eqn | Bin 0 -> 224764 bytes src/cmd/eqn/over.c | 35 +++ src/cmd/eqn/paren.c | 135 +++++++++ src/cmd/eqn/pile.c | 76 +++++ src/cmd/eqn/prevy.tab.h | 57 ++++ src/cmd/eqn/shift.c | 116 ++++++++ src/cmd/eqn/size.c | 70 +++++ src/cmd/eqn/sqrt.c | 35 +++ src/cmd/eqn/text.c | 318 +++++++++++++++++++++ src/cmd/eqn/tuning.c | 153 ++++++++++ src/cmd/eqn/y.tab.h | 57 ++++ 29 files changed, 3679 insertions(+) create mode 100644 src/cmd/eqn/diacrit.c create mode 100644 src/cmd/eqn/e.h create mode 100644 src/cmd/eqn/eqn.c create mode 100644 src/cmd/eqn/eqn.y create mode 100644 src/cmd/eqn/eqnbox.c create mode 100644 src/cmd/eqn/font.c create mode 100644 src/cmd/eqn/fromto.c create mode 100644 src/cmd/eqn/funny.c create mode 100644 src/cmd/eqn/glob.c create mode 100644 src/cmd/eqn/input.c create mode 100644 src/cmd/eqn/integral.c create mode 100644 src/cmd/eqn/lex.c create mode 100644 src/cmd/eqn/lookup.c create mode 100644 src/cmd/eqn/main.c create mode 100644 src/cmd/eqn/mark.c create mode 100644 src/cmd/eqn/matrix.c create mode 100644 src/cmd/eqn/mkfile create mode 100644 src/cmd/eqn/move.c create mode 100755 src/cmd/eqn/o.eqn create mode 100644 src/cmd/eqn/over.c create mode 100644 src/cmd/eqn/paren.c create mode 100644 src/cmd/eqn/pile.c create mode 100644 src/cmd/eqn/prevy.tab.h create mode 100644 src/cmd/eqn/shift.c create mode 100644 src/cmd/eqn/size.c create mode 100644 src/cmd/eqn/sqrt.c create mode 100644 src/cmd/eqn/text.c create mode 100644 src/cmd/eqn/tuning.c create mode 100644 src/cmd/eqn/y.tab.h (limited to 'src/cmd/eqn') diff --git a/src/cmd/eqn/diacrit.c b/src/cmd/eqn/diacrit.c new file mode 100644 index 00000000..10dc8c75 --- /dev/null +++ b/src/cmd/eqn/diacrit.c @@ -0,0 +1,75 @@ +#include "e.h" +#include "y.tab.h" + +extern double Dvshift, Dhshift, Dh2shift, Dheight, Barv, Barh, Ubarv, Ubarh; + +void diacrit(int p1, int type) +{ + int c, t; + + c = salloc(); + t = salloc(); + nrwid(p1, ps, p1); + printf(".nr 10 %gm\n", max(REL(eht[p1]-ebase[p1]-1,ps), 0)); /* vert shift if high */ + if (type == HIGHBAR) + printf(".nr 10 \\n(10+%gm\n", Dvshift); + else if (type == LOWBAR) + printf(".nr 10 0\n"); + else + printf(".if \\n(ct>1 .nr 10 \\n(10+%gm\n", Dvshift); + printf(".nr %d %gm\n", t, Dhshift); /* horiz shift if high */ + printf(".if \\n(ct>1 .nr %d %gm\n", t, Dh2shift); /* was .1 and .15 */ + switch (type) { + case VEC: + printf(".ds %d %s\n", c, lookup(deftbl, "vec_def")->cval); + break; + case DYAD: + printf(".ds %d %s\n", c, lookup(deftbl, "dyad_def")->cval); + break; + case HAT: + printf(".ds %d %s\n", c, lookup(deftbl, "hat_def")->cval); + break; + case TILDE: + printf(".ds %d %s\n", c, lookup(deftbl, "tilde_def")->cval); + break; + case DOT: + printf(".ds %d %s\n", c, lookup(deftbl, "dot_def")->cval); + break; + case DOTDOT: + printf(".ds %d %s\n", c, lookup(deftbl, "dotdot_def")->cval); + break; + case BAR: + case LOWBAR: + case HIGHBAR: + printf(".ds %d \\v'%gm'\\h'%gm'\\l'\\n(%du-%gm'\\h'%gm'\\v'%gm'\n", + c, -Barv, Barh, p1, 2*Barh, Barh, Barv); + break; + case UNDER: + printf(".ds %d \\v'%gm'\\l'\\n(%du-%gm\\(ul'\\h'%gm'\\v'%gm'\n", + c, -Ubarv, p1, Ubarh, Ubarh, Ubarv); + /* printf(".ds %d \\v'-%gm'\\l'\\n(%du\\(ul'\\v'%gm'\n", + c, Ubarv, p1, Ubarv); + */ + printf(".nr %d 0\n", t); + printf(".nr 10 0-.1m-%gm\n", REL(ebase[p1],ps)); + printf(".if \\n(ct%%2=1 .nr 10 0\\n(10-.1m\n"); + break; + case UTILDE: + printf(".ds %d %s\n", c, lookup(deftbl, "utilde_def")->cval); + printf(".nr %d 0\n", t); + printf(".nr 10 0-%gm\n", REL(ebase[p1],ps)); + printf(".if \\n(ct%%2=1 .nr 10 0\\n(10-%gm\n", 0.1); + break; + } + nrwid(c, ps, c); + if (lfont[p1] != ITAL) + printf(".nr %d 0\n", t); + printf(".as %d \\h'-\\n(%du-\\n(%du/2u+\\n(%du'\\v'0-\\n(10u'\\*(%d", + p1, p1, c, t, c); + printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u-\\n(%du'\n", c, p1, t); + if (type != UNDER && type != UTILDE) + eht[p1] += EM(Dheight, ps); /* was .15 */ + dprintf(".\tdiacrit: %c over S%d, lf=%c, rf=%c, h=%g, b=%g\n", + type, p1, lfont[p1], rfont[p1], eht[p1], ebase[p1]); + sfree(c); sfree(t); +} diff --git a/src/cmd/eqn/e.h b/src/cmd/eqn/e.h new file mode 100644 index 00000000..70c47023 --- /dev/null +++ b/src/cmd/eqn/e.h @@ -0,0 +1,166 @@ +#include +#include +#include + +enum charclass { + OTHER, OLET, ILET, DIG, LPAR, RPAR, SLASH, PLUS, ILETF, ILETJ, VBAR, + NONE, LAST +}; +extern int class[LAST][LAST]; + +#define dprintf if (dbg) printf +#define max(x,y) (((x) >= (y)) ? (x) : (y)) /* beware of side effects */ +#define min(x,y) (((x) <= (y)) ? (x) : (y)) + +extern char errbuf[200]; +extern char *cmdname; +#define ERROR sprintf(errbuf, +#define FATAL ), error(1, errbuf) +#define WARNING ), error(0, errbuf) +#define SYNTAX ), yyerror(errbuf) + +#define ROM '1' +#define ITAL '2' +#define BLD '3' +#define BDIT '4' + +#define DEFGAP -999 /* default gap in piles */ + +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 dps_set; /* 1 => -p option used */ +extern int gsize; /* global size */ +extern int ft; /* default font */ +extern int display; /* 1 => inline, 0 => .EQ/.EN */ +extern int synerr; /* 1 if syntax error in this eqn */ + +extern char *typesetter; /* typesetter name for -T... */ +extern int minsize; /* min size it can print */ +extern int ttype; /* actual type of typesetter: */ + +#define DEVCAT 1 +#define DEV202 2 +#define DEVAPS 3 +#define DEVPOST 4 + +extern double eht[]; +extern double ebase[]; +extern int lfont[]; +extern int rfont[]; +extern int lclass[]; +extern int rclass[]; +extern int yyval; +extern int yylval; +extern int eqnreg; +extern double eqnht; +extern int lefteq, righteq; +extern int markline; /* 1 if this EQ/EN contains mark or lineup */ + +#define TBLSIZE 100 + +typedef struct s_tbl { + char *name; /* e.g., "max" or "sum" */ + char *cval; /* e.g., "\\f1max\\fP" */ + int ival; /* or SUM */ + struct s_tbl *next; +} tbl; + +extern char *spaceval; /* use in place of normal \x (for pic) */ + +#define String 01 +#define Macro 02 +#define File 04 +#define Char 010 +#define Free 040 + +typedef struct infile { + FILE *fin; + char *fname; + int lineno; +} Infile; + +typedef struct { /* input source */ + int type; /* Macro, String, File */ + char *sp; /* if String or Macro */ +} Src; + +extern Src src[], *srcp; /* input source stack */ + +#define MAXARGS 20 +typedef struct { /* argument stack */ + char *argstk[MAXARGS]; /* pointers to args */ + char *argval; /* points to space containing args */ +} Arg; + +typedef struct { /* font number and name */ + int ft; + char name[10]; +} Font; + +extern Font ftstack[]; +extern Font *ftp; + +extern int szstack[]; +extern int nszstack; + +extern Infile infile[10]; +extern Infile *curfile; + +extern tbl *lookup(tbl **tblp, char *name); +extern void install(tbl **tblp, char *name, char *cval, int ival); +extern tbl *keytbl[], *deftbl[], *restbl[], *ftunetbl[]; + +extern int salloc(void); +extern void sfree(int); +extern void nrwid(int, int, int); +extern char *ABSPS(int); +extern char *DPS(int, int); +extern int EFFPS(int); +extern double EM(double, int); +extern double REL(double, int); +extern char *pad(int); +extern void getstr(char *, int); +extern char *strsave(char *); + +extern int input(void); +extern int unput(int); +extern void pbstr(char *); +extern void error(int, char *); +extern void yyerror(char *); + +extern void diacrit(int, int); +extern void eqnbox(int, int, int); +extern void setfont(char *); +extern void font(int, int); +extern void globfont(void); +extern void fatbox(int); +extern void fromto(int, int, int); +extern void funny(int); +extern void integral(int, int, int); +extern void setintegral(void); +extern void pushsrc(int, char *); +extern void popsrc(void); +extern void putout(int); +extern void text(int, char *); +extern void subsup(int, int, int); +extern void bshiftb(int, int, int); +extern void shift2(int, int, int); +extern void setsize(char *); +extern void size(int, int); +extern void globsize(void); +#define sqrt esqrt +extern void sqrt(int); +extern void text(int, char *); +extern void boverb(int, int); +extern void lineup(int); +extern void mark(int); +extern void paren(int, int, int); +extern void move(int, int, int); +extern void pile(int); +extern int startcol(int); +extern void column(int, int); +extern void matrix(int); diff --git a/src/cmd/eqn/eqn.c b/src/cmd/eqn/eqn.c new file mode 100644 index 00000000..527e5e08 --- /dev/null +++ b/src/cmd/eqn/eqn.c @@ -0,0 +1,741 @@ +#define CONTIG 57346 +#define QTEXT 57347 +#define SPACE 57348 +#define THIN 57349 +#define TAB 57350 +#define MATRIX 57351 +#define LCOL 57352 +#define CCOL 57353 +#define RCOL 57354 +#define COL 57355 +#define ABOVE 57356 +#define MARK 57357 +#define LINEUP 57358 +#define SUM 57359 +#define INT 57360 +#define PROD 57361 +#define UNION 57362 +#define INTER 57363 +#define DEFINE 57364 +#define TDEFINE 57365 +#define NDEFINE 57366 +#define DELIM 57367 +#define GSIZE 57368 +#define GFONT 57369 +#define INCLUDE 57370 +#define IFDEF 57371 +#define DOTEQ 57372 +#define DOTEN 57373 +#define FROM 57374 +#define TO 57375 +#define OVER 57376 +#define SQRT 57377 +#define SUP 57378 +#define SUB 57379 +#define SIZE 57380 +#define FONT 57381 +#define ROMAN 57382 +#define ITALIC 57383 +#define BOLD 57384 +#define FAT 57385 +#define UP 57386 +#define DOWN 57387 +#define BACK 57388 +#define FWD 57389 +#define LEFT 57390 +#define RIGHT 57391 +#define DOT 57392 +#define DOTDOT 57393 +#define HAT 57394 +#define TILDE 57395 +#define BAR 57396 +#define LOWBAR 57397 +#define HIGHBAR 57398 +#define UNDER 57399 +#define VEC 57400 +#define DYAD 57401 +#define UTILDE 57402 + +#line 17 "/usr/local/plan9/src/cmd/eqn/eqn.y" +#include "e.h" + +int yylex(void); +extern int yyerrflag; +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 150 +#endif +#ifndef YYSTYPE +#define YYSTYPE int +#endif +YYSTYPE yylval; +YYSTYPE yyval; +#define YYEOFCODE 1 +#define YYERRCODE 2 + +#line 140 "/usr/local/plan9/src/cmd/eqn/eqn.y" + +short yyexca[] = +{-1, 0, + 1, 3, + -2, 0, +-1, 1, + 1, -1, + -2, 0, +}; +#define YYNPROD 90 +#define YYPRIVATE 57344 +#define YYLAST 469 +short yyact[] = +{ + 4, 103, 119, 45, 27, 118, 104, 2, 102, 41, + 42, 43, 44, 65, 80, 81, 79, 66, 67, 68, + 69, 70, 50, 49, 74, 75, 76, 77, 105, 73, + 40, 80, 81, 80, 81, 114, 61, 64, 54, 62, + 57, 58, 59, 60, 55, 56, 63, 78, 91, 92, + 82, 26, 83, 85, 86, 87, 88, 90, 51, 52, + 48, 124, 50, 49, 117, 25, 45, 117, 72, 71, + 80, 81, 113, 24, 45, 23, 61, 64, 54, 62, + 57, 58, 59, 60, 55, 56, 63, 53, 89, 100, + 84, 22, 96, 95, 106, 107, 108, 109, 99, 110, + 111, 41, 42, 43, 44, 45, 98, 115, 21, 94, + 93, 18, 130, 123, 17, 116, 121, 46, 112, 125, + 127, 128, 1, 129, 126, 0, 0, 45, 8, 7, + 9, 10, 11, 28, 41, 42, 43, 44, 0, 16, + 47, 12, 34, 13, 14, 15, 61, 64, 54, 62, + 57, 58, 59, 60, 55, 56, 63, 0, 0, 20, + 0, 0, 29, 33, 30, 31, 32, 19, 37, 39, + 38, 36, 35, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 97, 8, 7, 9, + 10, 11, 28, 41, 42, 43, 44, 0, 16, 47, + 12, 34, 13, 14, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, + 0, 29, 33, 30, 31, 32, 19, 37, 39, 38, + 36, 35, 101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 6, 8, 7, 9, 10, 11, + 28, 41, 42, 43, 44, 0, 16, 5, 12, 34, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 29, + 33, 30, 31, 32, 19, 37, 39, 38, 36, 35, + 0, 0, 8, 7, 9, 10, 11, 28, 41, 42, + 43, 44, 6, 16, 47, 12, 34, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 0, 29, 33, 30, 31, + 32, 19, 37, 39, 38, 36, 35, 0, 0, 8, + 7, 9, 10, 11, 28, 41, 42, 43, 44, 6, + 16, 5, 12, 34, 13, 14, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 20, 0, 0, 29, 33, 30, 31, 32, 19, 37, + 39, 38, 36, 35, 8, 7, 9, 10, 11, 28, + 41, 42, 43, 44, 0, 16, 6, 12, 34, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 29, 33, + 30, 31, 32, 19, 37, 39, 38, 36, 35, 51, + 122, 48, 0, 50, 49, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 120, 49, 0, 61, 64, 54, + 62, 57, 58, 59, 60, 55, 56, 63, 61, 64, + 54, 62, 57, 58, 59, 60, 55, 56, 63 +}; +short yypact[] = +{ + 241,-1000, 288,-1000, 26,-1000, 335,-1000,-1000,-1000, +-1000,-1000,-1000,-1000,-1000,-1000, 380, 380, 380, 380, + 380, 32, 335, 380, 380, 380, 380,-1000,-1000, 66, +-1000,-1000,-1000, 66,-1000, 29, 66, 66, 66, 66, + 27,-1000,-1000,-1000,-1000, 26,-1000, 380, 380,-1000, +-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, +-1000,-1000,-1000,-1000,-1000, 124, 26, 96, 96, 96, + -14,-1000,-1000, 183, 96, 96, 96, 96, -53,-1000, +-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 335, +-1000, 26, -14, 380, 380, 380, 380,-1000, 380, 380, +-1000, 10, 91, 53, 288, -56, 408, -14, 397, 26, + 408, -14,-1000,-1000, -1,-1000,-1000, 335, 335,-1000, + 380,-1000, 380,-1000,-1000,-1000, 288, 50, -14, 26, +-1000 +}; +short yypgo[] = +{ + 0, 122, 6, 0, 117, 2, 116, 114, 111, 110, + 109, 108, 106, 98, 93, 92, 91, 89, 87, 75, + 73, 65, 51, 4, 47, 35, 16, 30, 1, 28 +}; +short yyr1[] = +{ + 0, 1, 1, 1, 2, 2, 2, 2, 4, 5, + 5, 6, 6, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, + 3, 10, 3, 12, 3, 13, 3, 3, 14, 3, + 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 24, 3, 11, 19, 20, 21, 22, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 16, 16, + 17, 17, 25, 25, 23, 29, 23, 27, 27, 27, + 27, 28, 28, 7, 8, 8, 8, 8, 26, 26 +}; +short yyr2[] = +{ + 0, 1, 1, 0, 1, 2, 2, 1, 2, 2, + 0, 2, 0, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 2, 2, 2, 2, 2, 0, + 5, 0, 4, 0, 5, 0, 4, 1, 0, 5, + 0, 4, 3, 2, 2, 2, 2, 2, 2, 1, + 0, 5, 1, 2, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 1, 2, 4, 0, 6, 1, 1, 1, + 1, 1, 3, 2, 1, 1, 1, 2, 1, 1 +}; +short yychk[] = +{ +-1000, -1, -2, 2, -3, 16, 61, 5, 4, 6, + 7, 8, 17, 19, 20, 21, 15, -7, -8, 43, + 35, -11, -16, -19, -20, -21, -22, -23, 9, 38, + 40, 41, 42, 39, 18, 48, 47, 44, 46, 45, + -27, 10, 11, 12, 13, -3, -4, 16, 34, 37, + 36, 32, 33, -18, 52, 58, 59, 54, 55, 56, + 57, 50, 53, 60, 51, -2, -3, -3, -3, -3, + -3, 37, 36, -2, -3, -3, -3, -3, -24, -26, + 4, 5, -26, -26, 61, -26, -26, -26, -26, 61, + -26, -3, -3, -9, -10, -14, -15, 62, -12, -13, + -17, 49, 61, -28, -2, -29, -3, -3, -3, -3, + -3, -3, -26, 62, -25, -23, 62, 14, 61, -5, + 36, -6, 33, -5, 62, -23, -2, -28, -3, -3, + 62 +}; +short yydef[] = +{ + -2, -2, 1, 2, 4, 7, 0, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, + 0, 37, 0, 0, 0, 0, 0, 49, 50, 0, + 84, 85, 86, 0, 52, 0, 0, 0, 0, 0, + 0, 77, 78, 79, 80, 5, 6, 0, 0, 29, + 31, 38, 40, 44, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 0, 24, 25, 26, 27, + 28, 33, 35, 43, 45, 46, 47, 48, 0, 83, + 88, 89, 87, 68, 69, 53, 54, 55, 56, 0, + 75, 8, 23, 0, 0, 0, 0, 13, 0, 0, + 42, 0, 0, 0, 81, 0, 10, 32, 12, 41, + 10, 36, 70, 71, 0, 72, 74, 0, 0, 30, + 0, 39, 0, 34, 51, 73, 82, 0, 9, 11, + 76 +}; +short yytok1[] = +{ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 61, 0, 62 +}; +short yytok2[] = +{ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60 +}; +long yytok3[] = +{ + 0 +}; +#define YYFLAG -1000 +#define YYERROR goto yyerrlab +#define YYACCEPT return(0) +#define YYABORT return(1) +#define yyclearin yychar = -1 +#define yyerrok yyerrflag = 0 + +#ifdef yydebug +#include "y.debug" +#else +#define yydebug 0 +char* yytoknames[1]; /* for debugging */ +char* yystates[1]; /* for debugging */ +#endif + +/* parser for yacc output */ + +int yynerrs = 0; /* number of errors */ +int yyerrflag = 0; /* error recovery flag */ + +char* +yytokname(int yyc) +{ + static char x[10]; + + if(yyc > 0 && yyc <= sizeof(yytoknames)/sizeof(yytoknames[0])) + if(yytoknames[yyc-1]) + return yytoknames[yyc-1]; + sprintf(x, "<%d>", yyc); + return x; +} + +char* +yystatname(int yys) +{ + static char x[10]; + + if(yys >= 0 && yys < sizeof(yystates)/sizeof(yystates[0])) + if(yystates[yys]) + return yystates[yys]; + sprintf(x, "<%d>\n", yys); + return x; +} + +long +yylex1(void) +{ + long yychar; + long *t3p; + int c; + + yychar = yylex(); + if(yychar <= 0) { + c = yytok1[0]; + goto out; + } + if(yychar < sizeof(yytok1)/sizeof(yytok1[0])) { + c = yytok1[yychar]; + goto out; + } + if(yychar >= YYPRIVATE) + if(yychar < YYPRIVATE+sizeof(yytok2)/sizeof(yytok2[0])) { + c = yytok2[yychar-YYPRIVATE]; + goto out; + } + for(t3p=yytok3;; t3p+=2) { + c = t3p[0]; + if(c == yychar) { + c = t3p[1]; + goto out; + } + if(c == 0) + break; + } + c = 0; + +out: + if(c == 0) + c = yytok2[1]; /* unknown char */ + if(yydebug >= 3) + printf("lex %.4lX %s\n", yychar, yytokname(c)); + return c; +} + +int +yyparse(void) +{ + struct + { + YYSTYPE yyv; + int yys; + } yys[YYMAXDEPTH], *yyp, *yypt; + short *yyxi; + int yyj, yym, yystate, yyn, yyg; + YYSTYPE save1, save2; + int save3, save4; + long yychar; + + save1 = yylval; + save2 = yyval; + save3 = yynerrs; + save4 = yyerrflag; + + yystate = 0; + yychar = -1; + yynerrs = 0; + yyerrflag = 0; + yyp = &yys[-1]; + goto yystack; + +ret0: + yyn = 0; + goto ret; + +ret1: + yyn = 1; + goto ret; + +ret: + yylval = save1; + yyval = save2; + yynerrs = save3; + yyerrflag = save4; + return yyn; + +yystack: + /* put a state and value onto the stack */ + if(yydebug >= 4) + printf("char %s in %s", yytokname(yychar), yystatname(yystate)); + + yyp++; + if(yyp >= &yys[YYMAXDEPTH]) { + yyerror("yacc stack overflow"); + goto ret1; + } + yyp->yys = yystate; + yyp->yyv = yyval; + +yynewstate: + yyn = yypact[yystate]; + if(yyn <= YYFLAG) + goto yydefault; /* simple state */ + if(yychar < 0) + yychar = yylex1(); + yyn += yychar; + if(yyn < 0 || yyn >= YYLAST) + goto yydefault; + yyn = yyact[yyn]; + if(yychk[yyn] == yychar) { /* valid shift */ + yychar = -1; + yyval = yylval; + yystate = yyn; + if(yyerrflag > 0) + yyerrflag--; + goto yystack; + } + +yydefault: + /* default state action */ + yyn = yydef[yystate]; + if(yyn == -2) { + if(yychar < 0) + yychar = yylex1(); + + /* look through exception table */ + for(yyxi=yyexca;; yyxi+=2) + if(yyxi[0] == -1 && yyxi[1] == yystate) + break; + for(yyxi += 2;; yyxi += 2) { + yyn = yyxi[0]; + if(yyn < 0 || yyn == yychar) + break; + } + yyn = yyxi[1]; + if(yyn < 0) + goto ret0; + } + if(yyn == 0) { + /* error ... attempt to resume parsing */ + switch(yyerrflag) { + case 0: /* brand new error */ + yyerror("syntax error"); + if(yydebug >= 1) { + printf("%s", yystatname(yystate)); + printf("saw %s\n", yytokname(yychar)); + } +yyerrlab: + yynerrs++; + + case 1: + case 2: /* incompletely recovered error ... try again */ + yyerrflag = 3; + + /* find a state where "error" is a legal shift action */ + while(yyp >= yys) { + yyn = yypact[yyp->yys] + YYERRCODE; + if(yyn >= 0 && yyn < YYLAST) { + yystate = yyact[yyn]; /* simulate a shift of "error" */ + if(yychk[yystate] == YYERRCODE) + goto yystack; + } + + /* the current yyp has no shift onn "error", pop stack */ + if(yydebug >= 2) + printf("error recovery pops state %d, uncovers %d\n", + yyp->yys, (yyp-1)->yys ); + yyp--; + } + /* there is no state on the stack with an error shift ... abort */ + goto ret1; + + case 3: /* no shift yet; clobber input char */ + if(yydebug >= YYEOFCODE) + printf("error recovery discards %s\n", yytokname(yychar)); + if(yychar == YYEOFCODE) + goto ret1; + yychar = -1; + goto yynewstate; /* try again in the same state */ + } + } + + /* reduction by production yyn */ + if(yydebug >= 2) + printf("reduce %d in:\n\t%s", yyn, yystatname(yystate)); + + yypt = yyp; + yyp -= yyr2[yyn]; + yyval = (yyp+1)->yyv; + yym = yyn; + + /* consult goto table to find next state */ + yyn = yyr1[yyn]; + yyg = yypgo[yyn]; + yyj = yyg + yyp->yys + 1; + + if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn) + yystate = yyact[yyg]; + switch(yym) { + +case 1: +#line 24 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ putout(yypt[-0].yyv); } break; +case 2: +#line 25 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ ERROR "syntax error" WARNING; } break; +case 3: +#line 26 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ eqnreg = 0; } break; +case 5: +#line 30 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ eqnbox(yypt[-1].yyv, yypt[-0].yyv, 0); } break; +case 6: +#line 31 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ eqnbox(yypt[-1].yyv, yypt[-0].yyv, 1); } break; +case 7: +#line 32 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ lineup(0); } break; +case 8: +#line 35 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = yypt[-0].yyv; lineup(1); } break; +case 9: +#line 38 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = yypt[-0].yyv; } break; +case 10: +#line 39 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = 0; } break; +case 11: +#line 42 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = yypt[-0].yyv; } break; +case 12: +#line 43 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = 0; } break; +case 13: +#line 46 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = yypt[-1].yyv; } break; +case 14: +#line 47 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ text(QTEXT, (char *) yypt[-0].yyv); } break; +case 15: +#line 48 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ text(CONTIG, (char *) yypt[-0].yyv); } break; +case 16: +#line 49 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ text(SPACE, (char *) 0); } break; +case 17: +#line 50 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ text(THIN, (char *) 0); } break; +case 18: +#line 51 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ text(TAB, (char *) 0); } break; +case 19: +#line 52 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ funny(SUM); } break; +case 20: +#line 53 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ funny(PROD); } break; +case 21: +#line 54 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ funny(UNION); } break; +case 22: +#line 55 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ funny(INTER); } break; +case 23: +#line 56 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ boverb(yypt[-2].yyv, yypt[-0].yyv); } break; +case 24: +#line 57 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ mark(yypt[-0].yyv); } break; +case 25: +#line 58 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ size(yypt[-1].yyv, yypt[-0].yyv); } break; +case 26: +#line 59 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ font(yypt[-1].yyv, yypt[-0].yyv); } break; +case 27: +#line 60 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ fatbox(yypt[-0].yyv); } break; +case 28: +#line 61 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ sqrt(yypt[-0].yyv); } break; +case 29: +#line 62 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ps -= deltaps;} break; +case 30: +#line 62 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ subsup(yypt[-4].yyv, yypt[-1].yyv, yypt[-0].yyv); } break; +case 31: +#line 63 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ps -= deltaps;} break; +case 32: +#line 63 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ subsup(yypt[-3].yyv, 0, yypt[-0].yyv); } break; +case 33: +#line 64 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ps -= deltaps;} break; +case 34: +#line 64 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ integral(yypt[-4].yyv, yypt[-1].yyv, yypt[-0].yyv); } break; +case 35: +#line 65 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ps -= deltaps;} break; +case 36: +#line 65 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ integral(yypt[-3].yyv, 0, yypt[-0].yyv); } break; +case 37: +#line 66 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ integral(yypt[-0].yyv, 0, 0); } break; +case 38: +#line 67 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ps -= deltaps;} break; +case 39: +#line 67 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ fromto(yypt[-4].yyv, yypt[-1].yyv, yypt[-0].yyv); } break; +case 40: +#line 68 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ps -= deltaps;} break; +case 41: +#line 68 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ fromto(yypt[-3].yyv, 0, yypt[-0].yyv); } break; +case 42: +#line 69 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ paren(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv); } break; +case 43: +#line 70 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ paren(yypt[-1].yyv, yypt[-0].yyv, 0); } break; +case 44: +#line 71 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ diacrit(yypt[-1].yyv, yypt[-0].yyv); } break; +case 45: +#line 72 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ move(FWD, yypt[-1].yyv, yypt[-0].yyv); } break; +case 46: +#line 73 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ move(UP, yypt[-1].yyv, yypt[-0].yyv); } break; +case 47: +#line 74 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ move(BACK, yypt[-1].yyv, yypt[-0].yyv); } break; +case 48: +#line 75 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ move(DOWN, yypt[-1].yyv, yypt[-0].yyv); } break; +case 49: +#line 76 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ pile(yypt[-0].yyv); ct = yypt[-0].yyv; } break; +case 50: +#line 77 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{yyval=ct;} break; +case 51: +#line 77 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ matrix(yypt[-3].yyv); ct = yypt[-3].yyv; } break; +case 52: +#line 80 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ setintegral(); } break; +case 53: +#line 83 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = atoi((char *) yypt[-1].yyv); } break; +case 54: +#line 84 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = atoi((char *) yypt[-1].yyv); } break; +case 55: +#line 85 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = atoi((char *) yypt[-1].yyv); } break; +case 56: +#line 86 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = atoi((char *) yypt[-1].yyv); } break; +case 57: +#line 88 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = HAT; } break; +case 58: +#line 89 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = VEC; } break; +case 59: +#line 90 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = DYAD; } break; +case 60: +#line 91 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = BAR; } break; +case 61: +#line 92 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = LOWBAR; } break; +case 62: +#line 93 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = HIGHBAR; } break; +case 63: +#line 94 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = UNDER; } break; +case 64: +#line 95 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = DOT; } break; +case 65: +#line 96 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = TILDE; } break; +case 66: +#line 97 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = UTILDE; } break; +case 67: +#line 98 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = DOTDOT; } break; +case 68: +#line 101 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = ((char *)yypt[-0].yyv)[0]; } break; +case 69: +#line 102 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = '{'; } break; +case 70: +#line 105 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = ((char *)yypt[-0].yyv)[0]; } break; +case 71: +#line 106 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = '}'; } break; +case 74: +#line 113 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ column(yypt[-3].yyv, DEFGAP); } break; +case 75: +#line 114 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{yyval=atoi((char*)yypt[-0].yyv);} break; +case 76: +#line 114 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ column(yypt[-5].yyv, yypt[-3].yyv); } break; +case 77: +#line 117 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = startcol(LCOL); } break; +case 78: +#line 118 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = startcol(CCOL); } break; +case 79: +#line 119 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = startcol(RCOL); } break; +case 80: +#line 120 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = startcol(COL); } break; +case 81: +#line 123 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ lp[ct++] = yypt[-0].yyv; } break; +case 82: +#line 124 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ lp[ct++] = yypt[-0].yyv; } break; +case 83: +#line 127 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ yyval = ps; setsize((char *) yypt[-0].yyv); } break; +case 84: +#line 130 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ static char R[]="R"; setfont(R); } break; +case 85: +#line 131 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ static char I[]="I"; setfont(I); } break; +case 86: +#line 132 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ static char B[]="B"; setfont(B); } break; +case 87: +#line 133 "/usr/local/plan9/src/cmd/eqn/eqn.y" +{ setfont((char *)yypt[-0].yyv); } break; + } + goto yystack; /* stack new state and value */ +} diff --git a/src/cmd/eqn/eqn.y b/src/cmd/eqn/eqn.y new file mode 100644 index 00000000..74796d7f --- /dev/null +++ b/src/cmd/eqn/eqn.y @@ -0,0 +1,140 @@ +%term CONTIG QTEXT SPACE THIN TAB +%term MATRIX LCOL CCOL RCOL COL ABOVE +%term MARK LINEUP +%term SUM INT PROD UNION INTER +%term DEFINE TDEFINE NDEFINE DELIM GSIZE GFONT INCLUDE SPACE IFDEF +%term DOTEQ DOTEN + +%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 LOWBAR HIGHBAR UNDER VEC DYAD UTILDE + +%{ +#include "e.h" + +int yylex(void); +%} + +%% + +stuff : eqn { putout($1); } + | error { ERROR "syntax error" WARNING; } /* should be SYNTAX */ + | { 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); } + ; + +sbox : SUP box %prec SUP { $$ = $2; } + | %prec SUP { $$ = 0; } + ; + +tbox : TO box %prec TO { $$ = $2; } + | %prec FROM { $$ = 0; } + ; + +box : '{' eqn '}' { $$ = $2; } + | QTEXT { text(QTEXT, (char *) $1); } + | CONTIG { text(CONTIG, (char *) $1); } + | SPACE { text(SPACE, (char *) 0); } + | THIN { text(THIN, (char *) 0); } + | TAB { text(TAB, (char *) 0); } + | SUM { funny(SUM); } + | PROD { funny(PROD); } + | UNION { funny(UNION); } + | INTER { funny(INTER); } + | 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); } + | box SUB {ps -= deltaps;} box sbox %prec SUB { subsup($1, $4, $5); } + | box SUP {ps -= deltaps;} box %prec SUP { subsup($1, 0, $4); } + | int SUB {ps -= deltaps;} box sbox %prec SUB { integral($1, $4, $5); } + | int SUP {ps -= deltaps;} box %prec SUP { integral($1, 0, $4); } + | int { integral($1, 0, 0); } + | box FROM {ps -= deltaps;} box tbox %prec FROM { fromto($1, $4, $5); } + | box TO {ps -= deltaps;} box %prec TO { fromto($1, 0, $4); } + | left eqn right { paren($1, $2, $3); } + | left eqn { paren($1, $2, 0); } + | 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); } + | column { pile($1); ct = $1; } + | MATRIX {$$=ct;} '{' collist '}' { matrix($2); ct = $2; } + ; + +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; } + | LOWBAR { $$ = LOWBAR; } + | HIGHBAR { $$ = HIGHBAR; } + | UNDER { $$ = UNDER; } /* underbar */ + | DOT { $$ = DOT; } + | TILDE { $$ = TILDE; } + | UTILDE { $$ = UTILDE; } + | DOTDOT { $$ = DOTDOT; } /* umlaut = double dot */ + ; + +left : LEFT text { $$ = ((char *)$2)[0]; } + | LEFT '{' { $$ = '{'; } + ; + +right : RIGHT text { $$ = ((char *)$2)[0]; } + | RIGHT '}' { $$ = '}'; } + ; + +collist : column + | collist column + ; + +column : col '{' list '}' { column($1, DEFGAP); } + | col text {$$=atoi((char*)$2);} '{' list '}' { column($1, $3); } + ; + +col : LCOL { $$ = startcol(LCOL); } + | CCOL { $$ = startcol(CCOL); } + | RCOL { $$ = startcol(RCOL); } + | COL { $$ = startcol(COL); } + ; + +list : eqn { lp[ct++] = $1; } + | list ABOVE eqn { lp[ct++] = $3; } + ; + +size : SIZE text { $$ = ps; setsize((char *) $2); } + ; + +font : ROMAN { static char R[]="R"; setfont(R); } + | ITALIC { static char I[]="I"; setfont(I); } + | BOLD { static char B[]="B"; setfont(B); } + | FONT text { setfont((char *)$2); } + ; + +text : CONTIG + | QTEXT + ; + +%% diff --git a/src/cmd/eqn/eqnbox.c b/src/cmd/eqn/eqnbox.c new file mode 100644 index 00000000..7dd0b867 --- /dev/null +++ b/src/cmd/eqn/eqnbox.c @@ -0,0 +1,24 @@ +#include "e.h" + +void eqnbox(int p1, int p2, int lu) +{ + double b, h; + char *sh; + extern char *IRspace; + + yyval = p1; + b = max(ebase[p1], ebase[p2]); + eht[yyval] = h = b + max(eht[p1]-ebase[p1], + eht[p2]-ebase[p2]); + ebase[yyval] = b; + dprintf(".\tS%d <- %d %d; b=%g, h=%g\n", yyval, p1, p2, b, h); + sh = pad(class[rclass[p1]][lclass[p2]]); + if (lu) { + printf(".nr %d \\w'\\*(%d%s'\n", p1, p1, sh); + printf(".ds %d \\h'|\\n(09u-\\n(%du'\\*(%d\n", p1, p1, p1); + } + printf(".as %d \"%s\\*(%d\n", yyval, sh, p2); + rfont[p1] = rfont[p2]; + rclass[p1] = rclass[p2]; + sfree(p2); +} diff --git a/src/cmd/eqn/font.c b/src/cmd/eqn/font.c new file mode 100644 index 00000000..3fb01119 --- /dev/null +++ b/src/cmd/eqn/font.c @@ -0,0 +1,70 @@ +# include "e.h" + +void setfont(char *ch1) +{ + yyval = ft; + if (strcmp(ch1, "I") == 0) { /* I and italic mean merely position 2 */ + *ch1 = '2'; + ft = ITAL; + } else if (strcmp(ch1, "B") == 0) { /* and similarly for B & bold */ + *ch1 = '3'; + ft = BLD; + } else if (strcmp(ch1, "R") == 0) { /* and R and roman */ + *ch1 = '1'; + ft = ROM; + } else { + ft = ROM; /* assume it's a roman style */ + } + ftp++; + if (ftp >= &ftstack[10]) + ERROR "font stack overflow (10)" FATAL; + ftp->ft = ft; + if (ch1[1] == 0) { /* 1-char name */ + ftp->name[0] = *ch1; + ftp->name[1] = '\0'; + } else + sprintf(ftp->name, "(%s", ch1); + dprintf(".\tsetfont %s %c\n", ch1, ft); +} + +void font(int p1, int p2) +{ + /* old font in p1, new in ft */ + yyval = p2; + lfont[yyval] = rfont[yyval] = ft==ITAL ? ITAL : ROM; + ftp--; + ft = p1; +} + +void globfont(void) +{ + char temp[20]; + + getstr(temp, sizeof(temp)); + yyval = eqnreg = 0; + if (strcmp(temp, "I") == 0 || strncmp(temp, "it", 2) == 0) { + ft = ITAL; + strcpy(temp, "2"); + } else if (strcmp(temp, "B") == 0 || strncmp(temp, "bo", 2) == 0) { + ft = BLD; + strcpy(temp, "3"); + } else if (strcmp(temp, "R") == 0 || strncmp(temp, "ro", 2) == 0) { + ft = ROM; + strcpy(temp, "1"); + } else { + ft = ROM; /* assume it's a roman style */ + } + ftstack[0].ft = ft; + if (temp[1] == 0) /* 1-char name */ + strcpy(ftstack[0].name, temp); + else + sprintf(ftstack[0].name, "(%.2s", temp); +} + +void fatbox(int p) +{ + extern double Fatshift; + + yyval = p; + printf(".ds %d \\*(%d\\h'-\\w'\\*(%d'u+%gm'\\*(%d\n", p, p, p, Fatshift, p); +} diff --git a/src/cmd/eqn/fromto.c b/src/cmd/eqn/fromto.c new file mode 100644 index 00000000..2d4d7f74 --- /dev/null +++ b/src/cmd/eqn/fromto.c @@ -0,0 +1,52 @@ +# include "e.h" + +void fromto(int p1, int p2, int p3) +{ + double b, h1, b1, t; + int subps; + + yyval = salloc(); + lfont[yyval] = rfont[yyval] = 0; + h1 = eht[yyval] = eht[p1]; + b1 = ebase[p1]; + b = 0; + subps = ps; + ps += deltaps; + nrwid(p1, ps, p1); + printf(".nr %d \\n(%d\n", yyval, p1); + if (p2 > 0) { + nrwid(p2, subps, 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, subps, 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) { + t = eht[p2]-ebase[p2]+b1; + printf("\\v'%gm'\\h'\\n(%du-\\n(%du/2u'%s\\*(%d%s", + REL(t,ps), yyval, p2, DPS(ps,subps), p2, DPS(subps,ps)); + printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%gm'\\\n", + yyval, p2, REL(-t,ps)); + } + printf("\\h'\\n(%du-\\n(%du/2u'\\*(%d\\h'\\n(%du-\\n(%du/2u'\\\n", + yyval, p1, p1, yyval, p1); + if (p3 >0) { + t = h1-b1+ebase[p3]; + printf("\\v'%gm'\\h'-\\n(%du-\\n(%du/2u'%s\\*(%d%s\\h'\\n(%du-\\n(%du/2u'\\v'%gm'\\\n", + REL(-t,ps), yyval, p3, DPS(ps,subps), p3, DPS(subps,ps), yyval, p3, REL(t,ps)); + } + printf("\n"); + ebase[yyval] = b + b1; + dprintf(".\tS%d <- %d from %d to %d; h=%g b=%g\n", + yyval, p1, p2, p3, eht[yyval], ebase[yyval]); + sfree(p1); + if (p2 > 0) + sfree(p2); + if (p3 > 0) + sfree(p3); +} diff --git a/src/cmd/eqn/funny.c b/src/cmd/eqn/funny.c new file mode 100644 index 00000000..85955fce --- /dev/null +++ b/src/cmd/eqn/funny.c @@ -0,0 +1,30 @@ +#include "e.h" +#include "y.tab.h" + +extern int Funnyps; +extern double Funnyht, Funnybase; + +void funny(int n) +{ + char *f = 0; + + yyval = salloc(); + switch (n) { + case SUM: + f = lookup(deftbl, "sum_def")->cval; break; + case UNION: + f = lookup(deftbl, "union_def")->cval; break; + case INTER: /* intersection */ + f = lookup(deftbl, "inter_def")->cval; break; + case PROD: + f = lookup(deftbl, "prod_def")->cval; break; + default: + ERROR "funny type %d in funny", n FATAL; + } + printf(".ds %d %s\n", yyval, f); + eht[yyval] = EM(1.0, ps+Funnyps) - EM(Funnyht, ps); + ebase[yyval] = EM(Funnybase, ps); + dprintf(".\tS%d <- %s; h=%g b=%g\n", + yyval, f, eht[yyval], ebase[yyval]); + lfont[yyval] = rfont[yyval] = ROM; +} diff --git a/src/cmd/eqn/glob.c b/src/cmd/eqn/glob.c new file mode 100644 index 00000000..6ca1a1da --- /dev/null +++ b/src/cmd/eqn/glob.c @@ -0,0 +1,35 @@ +#include "e.h" + + /* YOU MAY WANT TO CHANGE THIS */ +char *typesetter = "post"; /* type of typesetter today */ +int ttype = DEVPOST; +int minsize = 4; /* min size it can handle */ + + +int dbg; /* debugging print if non-zero */ +int lp[200]; /* 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 dps_set = 0; /* 1 => -p option used */ +int gsize = 10; /* default initial point size */ +int ft = '2'; +Font ftstack[10] = { '2', "2" }; /* bottom is global font */ +Font *ftp = ftstack; +int szstack[10]; /* non-zero if absolute size set at this level */ +int nszstack = 0; +int display = 0; /* 1=>display, 0=>.EQ/.EN */ + +int synerr; /* 1 if syntax err in this eqn */ +double eht[100]; /* height in ems at gsize */ +double ebase[100]; /* base: where one enters above bottom */ +int lfont[100]; /* leftmost and rightmost font associated with this thing */ +int rfont[100]; +int lclass[100]; /* leftmost and rightmost class associated with this thing */ +int rclass[100]; +int eqnreg; /* register where final string appears */ +double eqnht; /* final height of equation */ +int lefteq = '\0'; /* left in-line delimiter */ +int righteq = '\0'; /* right in-line delimiter */ +int markline = 0; /* 1 if this EQ/EN contains mark; 2 if lineup */ diff --git a/src/cmd/eqn/input.c b/src/cmd/eqn/input.c new file mode 100644 index 00000000..3b865671 --- /dev/null +++ b/src/cmd/eqn/input.c @@ -0,0 +1,289 @@ +#include "e.h" +#include "y.tab.h" +#include +#include + +Infile infile[10]; +Infile *curfile = infile; + +#define MAXSRC 50 +Src src[MAXSRC]; /* input source stack */ +Src *srcp = src; + +extern int getarg(char *); +extern void eprint(void); + +void pushsrc(int type, char *ptr) /* new input source */ +{ + if (++srcp >= src + MAXSRC) + ERROR "inputs nested too deep" FATAL; + srcp->type = type; + srcp->sp = ptr; + if (dbg > 1) { + printf("\n%3d ", srcp - src); + switch (srcp->type) { + case File: + printf("push file %s\n", ((Infile *)ptr)->fname); + break; + case Macro: + printf("push macro <%s>\n", ptr); + break; + case Char: + printf("push char <%c>\n", *ptr); + break; + case String: + printf("push string <%s>\n", ptr); + break; + case Free: + printf("push free <%s>\n", ptr); + break; + default: + ERROR "pushed bad type %d\n", srcp->type FATAL; + } + } +} + +void popsrc(void) /* restore an old one */ +{ + if (srcp <= src) + ERROR "too many inputs popped" FATAL; + if (dbg > 1) { + printf("%3d ", srcp - src); + switch (srcp->type) { + case File: + printf("pop file\n"); + break; + case Macro: + printf("pop macro\n"); + break; + case Char: + printf("pop char <%c>\n", *srcp->sp); + break; + case String: + printf("pop string\n"); + break; + case Free: + printf("pop free\n"); + break; + default: + ERROR "pop weird input %d\n", srcp->type FATAL; + } + } + srcp--; +} + +Arg args[10]; /* argument frames */ +Arg *argfp = args; /* frame pointer */ +int argcnt; /* number of arguments seen so far */ + +void dodef(tbl *stp) /* collect args and switch input to defn */ +{ + int i, len; + char *p; + Arg *ap; + + ap = argfp+1; + if (ap >= args+10) + ERROR "more than arguments\n" FATAL; + argcnt = 0; + if (input() != '(') + ERROR "disaster in dodef\n"FATAL; + if (ap->argval == 0) + ap->argval = malloc(1000); + for (p = ap->argval; (len = getarg(p)) != -1; p += len) { + ap->argstk[argcnt++] = p; + if (input() == ')') + break; + } + for (i = argcnt; i < MAXARGS; i++) + ap->argstk[i] = ""; + if (dbg) + for (i = 0; i < argcnt; i++) + printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]); + argfp = ap; + pushsrc(Macro, stp->cval); +} + +getarg(char *p) /* pick up single argument, store in p, return length */ +{ + int n, c, npar; + + n = npar = 0; + for ( ;; ) { + c = input(); + if (c == EOF) + ERROR "end of file in getarg!\n" FATAL; + if (npar == 0 && (c == ',' || c == ')')) + break; + if (c == '"') /* copy quoted stuff intact */ + do { + *p++ = c; + n++; + } while ((c = input()) != '"' && c != EOF); + else if (c == '(') + npar++; + else if (c == ')') + npar--; + n++; + *p++ = c; + } + *p = 0; + unput(c); + return(n + 1); +} + +#define PBSIZE 2000 +char pbuf[PBSIZE]; /* pushback buffer */ +char *pb = pbuf-1; /* next pushed back character */ + +char ebuf[200]; /* collect input here for error reporting */ +char *ep = ebuf; + +input(void) +{ + register int c = 0; + + loop: + switch (srcp->type) { + case File: + c = getc(curfile->fin); + if (c == EOF) { + if (curfile == infile) + break; + if (curfile->fin != stdin) { + fclose(curfile->fin); + free(curfile->fname); /* assumes allocated */ + } + curfile--; + printf(".lf %d %s\n", curfile->lineno, curfile->fname); + popsrc(); + goto loop; + } + if (c == '\n') + curfile->lineno++; + break; + case Char: + if (pb >= pbuf) { + c = *pb--; + popsrc(); + break; + } else { /* can't happen? */ + popsrc(); + goto loop; + } + case String: + c = *srcp->sp++; + if (c == '\0') { + popsrc(); + goto loop; + } else { + if (*srcp->sp == '\0') /* empty, so pop */ + popsrc(); + break; + } + case Macro: + c = *srcp->sp++; + if (c == '\0') { + if (--argfp < args) + ERROR "argfp underflow" FATAL; + popsrc(); + goto loop; + } else if (c == '$' && isdigit(*srcp->sp)) { + int n = 0; + while (isdigit(*srcp->sp)) + n = 10 * n + *srcp->sp++ - '0'; + if (n > 0 && n <= MAXARGS) + pushsrc(String, argfp->argstk[n-1]); + goto loop; + } + break; + case Free: /* free string */ + free(srcp->sp); + popsrc(); + goto loop; + } + if (ep >= ebuf + sizeof ebuf) + ep = ebuf; + *ep++ = c; + return c; +} + + +unput(int c) +{ + if (++pb >= pbuf + sizeof pbuf) + ERROR "pushback overflow\n"FATAL; + if (--ep < ebuf) + ep = ebuf + sizeof(ebuf) - 1; + *pb = c; + pushsrc(Char, pb); + return c; +} + +void pbstr(char *s) +{ + pushsrc(String, s); +} + +void error(int die, char *s) +{ + extern char *cmdname; + + if (synerr) + return; + fprintf(stderr, "%s: ", cmdname); + fprintf(stderr, s); + if (errno > 0) + perror("???"); + if (curfile->fin) + fprintf(stderr, " near %s:%d", + curfile->fname, curfile->lineno+1); + fprintf(stderr, "\n"); + eprint(); + synerr = 1; + errno = 0; + if (die) { + if (dbg) + abort(); + else + exit(1); + } +} + +void yyerror(char *s) +{ + error(0, s); /* temporary */ +} + +char errbuf[200]; + +void eprint(void) /* try to print context around error */ +{ + char *p, *q; + + if (ep == ebuf) + return; /* no context */ + p = ep - 1; + if (p > ebuf && *p == '\n') + p--; + for ( ; p >= ebuf && *p != '\n'; p--) + ; + while (*p == '\n') + p++; + fprintf(stderr, " context is\n\t"); + for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) + ; + while (p < q) + putc(*p++, stderr); + fprintf(stderr, " >>> "); + while (p < ep) + putc(*p++, stderr); + fprintf(stderr, " <<< "); + while (pb >= pbuf) + putc(*pb--, stderr); + if (curfile->fin) + fgets(ebuf, sizeof ebuf, curfile->fin); + fprintf(stderr, "%s", ebuf); + pbstr("\n.EN\n"); /* safety first */ + ep = ebuf; +} diff --git a/src/cmd/eqn/integral.c b/src/cmd/eqn/integral.c new file mode 100644 index 00000000..2b1c9e3f --- /dev/null +++ b/src/cmd/eqn/integral.c @@ -0,0 +1,30 @@ +#include "e.h" +#include "y.tab.h" + +extern int Intps; +extern double Intht, Intbase, Int1h, Int1v, Int2h, Int2v; + +void integral(int p, int p1, int p2) +{ + if (p1 != 0) + printf(".ds %d \\h'%gm'\\v'%gm'\\*(%d\\v'%gm'\n", p1, -Int1h, Int1v, p1, -Int1v); + if (p2 != 0) + printf(".ds %d \\v'%gm'\\h'%gm'\\*(%d\\v'%gm'\n", p2, -Int2v, Int2h, p2, Int2v); + 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); + dprintf(".\tintegral: S%d; h=%g b=%g\n", p, eht[p], ebase[p]); + lfont[p] = ROM; +} + +void setintegral(void) +{ + yyval = salloc(); + printf(".ds %d %s\n", yyval, lookup(deftbl, "int_def")->cval); + eht[yyval] = EM(Intht, ps+Intps); + ebase[yyval] = EM(Intbase, ps); + lfont[yyval] = rfont[yyval] = ROM; +} diff --git a/src/cmd/eqn/lex.c b/src/cmd/eqn/lex.c new file mode 100644 index 00000000..e535b869 --- /dev/null +++ b/src/cmd/eqn/lex.c @@ -0,0 +1,265 @@ +#include "e.h" +#include "y.tab.h" +#include + +#define SSIZE 1000 +char token[SSIZE]; +int sp; + +void space(void); +void dodef(tbl *); +void define(int); +void ifdef(void); +void include(void); +void delim(void); + +yylex(void) +{ + register int c; + tbl *tp; + + begin: + while ((c = input()) == ' ' || c == '\n' || c == '\t') + ; + yylval = c; + switch (c) { + case EOF: + ERROR "unexpected end of input inside equation" WARNING; + return(EOF); + case '~': + return(SPACE); + case '^': + return(THIN); + /* case '\t': + return(TAB); + */ + case '{': + return('{'); + case '}': + return('}'); + case '"': + for (sp = 0; (c=input())!='"' && c != '\n'; ) { + if (c == '\\') + if ((c = input()) != '"') + token[sp++] = '\\'; + token[sp++] = c; + if (sp >= SSIZE) + ERROR "quoted string %.20s... too long", token FATAL; + } + token[sp] = '\0'; + yylval = (int) &token[0]; + if (c == '\n') + ERROR "missing \" in %.20s", token WARNING; + return(QTEXT); + } + if (!display && c == righteq) + return(EOF); + + unput(c); + getstr(token, SSIZE); + dprintf(".\tlex token = |%s|\n", token); + if ((tp = lookup(deftbl, token)) != NULL) { /* defined term */ + c = input(); + unput(c); + if (c == '(') /* macro with args */ + dodef(tp); + else { /* no args */ + unput(' '); + pbstr(tp->cval); + dprintf(".\tfound %s|=%s|\n", token, tp->cval); + } + goto begin; + } + + if ((tp = lookup(keytbl, token)) == NULL) /* not a keyword */ + return CONTIG; + + switch (tp->ival) { /* some kind of keyword */ + case DEFINE: case TDEFINE: case NDEFINE: + define(tp->ival); + break; + case IFDEF: + ifdef(); + break; + case DELIM: + delim(); + break; + case GSIZE: + globsize(); + break; + case GFONT: + globfont(); + break; + case INCLUDE: + include(); + break; + case SPACE: + space(); + break; + case DOTEQ: + /* .EQ inside equation -- should warn if at bottom level */ + break; + case DOTEN: + if (curfile == infile) + return EOF; + /* else ignore nested .EN */ + break; + default: + return tp->ival; + } + goto begin; +} + +void getstr(char *s, int n) +{ + register int c; + register char *p; + + p = s; + while ((c = input()) == ' ' || c == '\n') + ; + if (c == EOF) { + *s = 0; + return; + } + while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' + && c != '"' && c != '~' && c != '^') { + if (!display && c == righteq) + break; + if (c == '(' && p > s) { /* might be defined(...) */ + *p = '\0'; + if (lookup(deftbl, s) != NULL) + break; + } + if (c == '\\') + if ((c = input()) != '"') + *p++ = '\\'; + *p++ = c; + if (--n <= 0) + ERROR "token %.20s... too long", s FATAL; + c = input(); + } + unput(c); + *p = '\0'; + yylval = (int) s; +} + +cstr(char *s, int quote, int maxs) +{ + int del, c, i; + + s[0] = 0; + while ((del=input()) == ' ' || del == '\t') + ; + if (quote) + for (i=0; (c=input()) != del && c != EOF;) { + s[i++] = c; + if (i >= maxs) + return(1); /* disaster */ + } + else { + if (del == '\n') + return(1); + s[0] = del; + for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) { + s[i++] = c; + if (i >= maxs) + return(1); /* disaster */ + } + } + s[i] = '\0'; + if (c == EOF) + ERROR "Unexpected end of input at %.20s", s FATAL; + return(0); +} + +void define(int type) +{ + char *p1, *p2; + extern int ftune(char *, char *); + + 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 "Unterminated definition at %.20s", token FATAL; + if (lookup(ftunetbl, p1) != NULL) { /* double tuning param */ + dprintf(".\ttune %s %s\n", p1, token); + ftune(p1, token); + } else { + p2 = strsave(token); + install(deftbl, p1, p2, 0); + dprintf(".\tname %s defined as %s\n", p1, p2); + } +} + +void ifdef(void) /* do body if name is defined */ +{ + char name[100], *p; + + getstr(name, sizeof(name)); /* get name */ + cstr(token, 1, SSIZE); /* and body */ + if (lookup(deftbl, name) != NULL) { /* found it */ + p = strsave(token); + pushsrc(Free, p); + pushsrc(String, p); + } +} + +char *spaceval = NULL; + +void space(void) /* collect line of form "space amt" to replace \x in output */ +{ + getstr(token, SSIZE); + spaceval = strsave(token); + dprintf(".\tsetting spaceval to %s\n", token); +} + +char *strsave(char *s) +{ + register char *q; + + q = malloc(strlen(s)+1); + if (q == NULL) + ERROR "out of space in strsave on %s", s FATAL; + strcpy(q, s); + return(q); +} + +void include(void) +{ + char name[100]; + FILE *fin; + int c; + extern int errno; + + while ((c = input()) == ' ') + ; + unput(c); + cstr(name, c == '"', sizeof(name)); /* gets it quoted or not */ + if ((fin = fopen(name, "r")) == NULL) + ERROR "can't open file %s", name FATAL; + errno = 0; + curfile++; + curfile->fin = fin; + curfile->fname = strsave(name); + curfile->lineno = 0; + printf(".lf 1 %s\n", curfile->fname); + pushsrc(File, curfile->fname); +} + +void delim(void) +{ + yyval = eqnreg = 0; + if (cstr(token, 0, SSIZE)) + ERROR "Bizarre delimiters" FATAL; + lefteq = token[0]; + righteq = token[1]; + if (!isprint(lefteq) || !isprint(righteq)) + ERROR "Bizarre delimiters" FATAL; + if (lefteq == 'o' && righteq == 'f') + lefteq = righteq = '\0'; +} diff --git a/src/cmd/eqn/lookup.c b/src/cmd/eqn/lookup.c new file mode 100644 index 00000000..4eb94373 --- /dev/null +++ b/src/cmd/eqn/lookup.c @@ -0,0 +1,219 @@ +#include "e.h" +#include "y.tab.h" + +tbl *keytbl[TBLSIZE]; /* key words */ +tbl *restbl[TBLSIZE]; /* reserved words */ +tbl *deftbl[TBLSIZE]; /* user-defined names */ + +struct keyword { + char *key; + int keyval; +} keyword[] ={ + "sub", SUB, + "sup", SUP, + ".EN", DOTEN, + ".EQ", DOTEQ, + "from", FROM, + "to", TO, + "sum", SUM, + "hat", HAT, + "vec", VEC, + "dyad", DYAD, + "dot", DOT, + "dotdot", DOTDOT, + "bar", BAR, + "lowbar", LOWBAR, + "highbar", HIGHBAR, + "tilde", TILDE, + "utilde", UTILDE, + "under", UNDER, + "prod", PROD, + "int", INT, + "integral", INT, + "union", UNION, + "inter", INTER, + "matrix", MATRIX, + "col", COL, + "lcol", LCOL, + "ccol", CCOL, + "rcol", RCOL, + "pile", COL, /* synonyms ... */ + "lpile", LCOL, + "cpile", CCOL, + "rpile", RCOL, + "over", OVER, + "sqrt", SQRT, + "above", ABOVE, + "size", SIZE, + "font", FONT, + "fat", FAT, + "roman", ROMAN, + "italic", ITALIC, + "bold", BOLD, + "left", LEFT, + "right", RIGHT, + "delim", DELIM, + "define", DEFINE, + "tdefine", DEFINE, + "ndefine", NDEFINE, + "ifdef", IFDEF, + "gsize", GSIZE, + ".gsize", GSIZE, + "gfont", GFONT, + "include", INCLUDE, + "copy", INCLUDE, + "space", SPACE, + "up", UP, + "down", DOWN, + "fwd", FWD, + "back", BACK, + "mark", MARK, + "lineup", LINEUP, + 0, 0 +}; + +struct resword { + char *res; + char *resval; +} resword[] ={ + ">=", "\\(>=", + "<=", "\\(<=", + "==", "\\(==", + "!=", "\\(!=", + "+-", "\\(+-", + "->", "\\(->", + "<-", "\\(<-", + "inf", "\\(if", + "infinity", "\\(if", + "partial", "\\(pd", + "half", "\\f1\\(12\\fP", + "prime", "\\f1\\v'.5m'\\s+3\\(fm\\s-3\\v'-.5m'\\fP", + "dollar", "\\f1$\\fP", + "nothing", "", + "times", "\\(mu", + "del", "\\(gr", + "grad", "\\(gr", + "approx", "\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'", + "cdot", "\\v'-.3m'.\\v'.3m'", + "...", "\\v'-.25m'\\ .\\ .\\ .\\ \\v'.25m'", + ",...,", "\\f1,\\fP\\ .\\ .\\ .\\ \\f1,\\fP\\|", + "alpha", "α", + "ALPHA", "Α", + "beta", "β", + "BETA", "Β", + "gamma", "γ", + "GAMMA", "Γ", + "delta", "δ", + "DELTA", "Δ", + "epsilon", "ε", + "EPSILON", "Ε", + "omega", "ω", + "OMEGA", "Ω", + "lambda", "λ", + "LAMBDA", "Λ", + "mu", "μ", + "MU", "Μ", + "nu", "ν", + "NU", "Ν", + "theta", "θ", + "THETA", "Θ", + "phi", "φ", + "PHI", "Φ", + "pi", "π", + "PI", "Π", + "sigma", "σ", + "SIGMA", "Σ", + "xi", "ξ", + "XI", "Ξ", + "zeta", "ζ", + "ZETA", "Ζ", + "iota", "ι", + "IOTA", "Ι", + "eta", "η", + "ETA", "Η", + "kappa", "κ", + "KAPPA", "Κ", + "rho", "ρ", + "RHO", "Ρ", + "tau", "τ", + "TAU", "Τ", + "omicron", "ο", + "OMICRON", "Ο", + "upsilon", "υ", + "UPSILON", "Υ", + "psi", "ψ", + "PSI", "Ψ", + "chi", "χ", + "CHI", "Χ", + "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", + "ln", "\\f1ln\\fP", + "max", "\\f1max\\fP", + "min", "\\f1min\\fP", + "exp", "\\f1exp\\fP", + "det", "\\f1det\\fP", + 0, 0 +}; + +int hash(char *s) +{ + register unsigned int h; + + for (h = 0; *s != '\0'; ) + h += *s++; + h %= TBLSIZE; + return h; +} + +tbl *lookup(tbl **tblp, char *name) /* find name in tbl */ +{ + register tbl *p; + + for (p = tblp[hash(name)]; p != NULL; p = p->next) + if (strcmp(name, p->name) == 0) + return(p); + return(NULL); +} + +void install(tbl **tblp, char *name, char *cval, int ival) /* install name, vals in tblp */ +{ + register tbl *p; + int h; + + if ((p = lookup(tblp, name)) == NULL) { + p = (tbl *) malloc(sizeof(tbl)); + if (p == NULL) + ERROR "out of space in install" FATAL; + h = hash(name); /* bad visibility here */ + p->name = name; + p->next = tblp[h]; + tblp[h] = p; + } + p->cval = cval; + p->ival = ival; +} + +void init_tbl(void) /* initialize tables */ +{ + int i; + extern int init_tune(void); + + for (i = 0; keyword[i].key != NULL; i++) + install(keytbl, keyword[i].key, (char *) 0, keyword[i].keyval); + for (i = 0; resword[i].res != NULL; i++) + install(restbl, resword[i].res, resword[i].resval, 0); + init_tune(); /* tuning table done in tuning.c */ +} diff --git a/src/cmd/eqn/main.c b/src/cmd/eqn/main.c new file mode 100644 index 00000000..a06fd165 --- /dev/null +++ b/src/cmd/eqn/main.c @@ -0,0 +1,333 @@ +#include "e.h" + +#define MAXLINE 3600 /* maximum input line */ + +char *version = "version Oct 24, 1991"; + +char in[MAXLINE]; /* input buffer */ +int noeqn; +char *cmdname; + +int yyparse(void); +void settype(char *); +int getdata(void); +int getline(char *); +#define inline einline +void inline(void); +void init(void); +void init_tbl(void); + +void +main(int argc, char *argv[]) +{ + char *p, buf[20]; + + cmdname = argv[0]; + if (p = getenv("TYPESETTER")) + typesetter = p; + while (argc > 1 && argv[1][0] == '-') { + switch (argv[1][1]) { + + case 'd': + if (argv[1][2] == '\0') { + dbg++; + printf("...\teqn %s\n", version); + } else { + lefteq = argv[1][2]; + righteq = argv[1][3]; + } + break; + case 's': szstack[0] = gsize = atoi(&argv[1][2]); break; + case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break; + case 'm': minsize = atoi(&argv[1][2]); break; + case 'f': strcpy(ftstack[0].name,&argv[1][2]); break; + case 'e': noeqn++; break; + case 'T': typesetter = &argv[1][2]; break; + default: + fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]); + break; + } + argc--; + argv++; + } + settype(typesetter); + sprintf(buf, "\"%s\"", typesetter); + install(deftbl, strsave(typesetter), strsave(buf), 0); + init_tbl(); /* install other keywords in tables */ + curfile = infile; + pushsrc(File, curfile->fname); + if (argc <= 1) { + curfile->fin = stdin; + curfile->fname = strsave("-"); + getdata(); + } else + while (argc-- > 1) { + if (strcmp(*++argv, "-") == 0) + curfile->fin = stdin; + else if ((curfile->fin = fopen(*argv, "r")) == NULL) + ERROR "can't open file %s", *argv FATAL; + curfile->fname = strsave(*argv); + getdata(); + if (curfile->fin != stdin) + fclose(curfile->fin); + } + exit(0); +} + +void settype(char *s) /* initialize data for particular typesetter */ + /* the minsize could profitably come from the */ +{ /* troff description file /usr/lib/font/dev.../DESC.out */ + if (strcmp(s, "202") == 0) + { minsize = 5; ttype = DEV202; } + else if (strcmp(s, "aps") == 0) + { minsize = 5; ttype = DEVAPS; } + else if (strcmp(s, "cat") == 0) + { minsize = 6; ttype = DEVCAT; } + else if (strcmp(s, "post") == 0) + { minsize = 4; ttype = DEVPOST; } + else + { minsize = 5; ttype = DEV202; } +} + +getdata(void) +{ + int i, type, ln; + char fname[100]; + extern int errno; + + errno = 0; + curfile->lineno = 0; + printf(".lf 1 %s\n", curfile->fname); + while ((type = getline(in)) != EOF) { + if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') { + for (i = 11; i < 100; i++) + used[i] = 0; + printf("%s", in); + if (markline) { /* turn off from last time */ + printf(".nr MK 0\n"); + markline = 0; + } + display = 1; + init(); + yyparse(); + if (eqnreg > 0) { + if (markline) + printf(".nr MK %d\n", markline); /* for -ms macros */ + printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht); + printf(".rn %d 10\n", eqnreg); + if (!noeqn) + printf("\\&\\*(10\n"); + } + printf(".EN"); + while (putchar(input()) != '\n') + ; + printf(".lf %d\n", curfile->lineno+1); + } + else if (type == lefteq) + inline(); + else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') { + if (sscanf(in+3, "%d %s", &ln, fname) == 2) { + free(curfile->fname); + printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname)); + } else + printf(".lf %d\n", curfile->lineno = ln); + } else + printf("%s", in); + } + return(0); +} + +getline(char *s) +{ + register c; + + while ((c=input()) != '\n' && c != EOF && c != lefteq) { + if (s >= in+MAXLINE) { + ERROR "input line too long: %.20s\n", in WARNING; + in[MAXLINE] = '\0'; + break; + } + *s++ = c; + } + if (c != lefteq) + *s++ = c; + *s = '\0'; + return(c); +} + +void inline(void) +{ + int ds, n, sz1 = 0; + + n = curfile->lineno; + if (szstack[0] != 0) + printf(".nr %d \\n(.s\n", sz1 = salloc()); + ds = salloc(); + printf(".rm %d \n", ds); + display = 0; + do { + if (*in) + printf(".as %d \"%s\n", ds, in); + init(); + yyparse(); + if (eqnreg > 0) { + printf(".as %d \\*(%d\n", ds, eqnreg); + sfree(eqnreg); + printf(".lf %d\n", curfile->lineno+1); + } + } while (getline(in) == lefteq); + if (*in) + printf(".as %d \"%s", ds, in); + if (sz1) + printf("\\s\\n(%d", sz1); + printf("\\*(%d\n", ds); + printf(".lf %d\n", curfile->lineno+1); + if (curfile->lineno > n+3) + fprintf(stderr, "eqn warning: multi-line %c...%c, file %s:%d,%d\n", + lefteq, righteq, curfile->fname, n, curfile->lineno); + sfree(ds); + if (sz1) sfree(sz1); +} + +void putout(int p1) +{ + double before, after; + extern double BeforeSub, AfterSub; + + dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]); + eqnht = eht[p1]; + before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */ + after = ebase[p1] - AfterSub; + if (spaceval || before > 0.01 || after > 0.01) { + printf(".ds %d ", p1); /* used to be \\x'0' here: why? */ + if (spaceval != NULL) + printf("\\x'0-%s'", spaceval); + else if (before > 0.01) + printf("\\x'0-%gm'", before); + printf("\\*(%d", p1); + if (spaceval == NULL && after > 0.01) + printf("\\x'%gm'", after); + putchar('\n'); + } + if (szstack[0] != 0) + printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1); + eqnreg = p1; + if (spaceval != NULL) { + free(spaceval); + spaceval = NULL; + } +} + +void init(void) +{ + synerr = 0; + ct = 0; + ps = gsize; + ftp = ftstack; + ft = ftp->ft; + nszstack = 0; + if (szstack[0] != 0) /* absolute gsize in effect */ + printf(".nr 99 \\n(.s\n"); +} + +salloc(void) +{ + int i; + + for (i = 11; i < 100; i++) + if (used[i] == 0) { + used[i]++; + return(i); + } + ERROR "no eqn strings left (%d)", i FATAL; + return(0); +} + +void sfree(int n) +{ + used[n] = 0; +} + +void nrwid(int n1, int p, int n2) +{ + printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */ +} + +char *ABSPS(int dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */ +{ + static char buf[100], *lb = buf; + char *p; + + if (lb > buf + sizeof(buf) - 10) + lb = buf; + p = lb; + *lb++ = '\\'; + *lb++ = 's'; + if (dn >= 10) { /* \s(dd only works in new troff */ + if (dn >= 40) + *lb++ = '('; + *lb++ = dn/10 + '0'; + *lb++ = dn%10 + '0'; + } else { + *lb++ = dn + '0'; + } + *lb++ = '\0'; + return p; +} + +char *DPS(int f, int t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */ +{ + static char buf[100], *lb = buf; + char *p; + int dn; + + if (lb > buf + sizeof(buf) - 10) + lb = buf; + p = lb; + *lb++ = '\\'; + *lb++ = 's'; + dn = EFFPS(t) - EFFPS(f); + if (szstack[nszstack] != 0) /* absolute */ + dn = EFFPS(t); /* should do proper \s(dd */ + else if (dn >= 0) + *lb++ = '+'; + else { + *lb++ = '-'; + dn = -dn; + } + if (dn >= 10) { /* \s+(dd only works in new troff */ + *lb++ = '('; + *lb++ = dn/10 + '0'; + *lb++ = dn%10 + '0'; + } else { + *lb++ = dn + '0'; + } + *lb++ = '\0'; + return p; +} + +EFFPS(int n) /* effective value of n */ +{ + if (n >= minsize) + return n; + else + return minsize; +} + +double EM(double m, int ps) /* convert m to ems in gsize */ +{ + m *= (double) EFFPS(ps) / gsize; + if (m <= 0.001 && m >= -0.001) + return 0; + else + return m; +} + +double REL(double m, int ps) /* convert m to ems in ps */ +{ + m *= (double) gsize / EFFPS(ps); + if (m <= 0.001 && m >= -0.001) + return 0; + else + return m; +} diff --git a/src/cmd/eqn/mark.c b/src/cmd/eqn/mark.c new file mode 100644 index 00000000..f02e6779 --- /dev/null +++ b/src/cmd/eqn/mark.c @@ -0,0 +1,19 @@ +#include "e.h" + +void mark(int p1) +{ + markline = 1; + printf(".ds %d \\k(09\\*(%d\n", p1, p1); + yyval = p1; + dprintf(".\tmark %d\n", p1); +} + +void lineup(int p1) +{ + markline = 2; + if (p1 == 0) { + yyval = salloc(); + printf(".ds %d \\h'|\\n(09u'\n", yyval); + } + dprintf(".\tlineup %d\n", p1); +} diff --git a/src/cmd/eqn/matrix.c b/src/cmd/eqn/matrix.c new file mode 100644 index 00000000..9df6cff2 --- /dev/null +++ b/src/cmd/eqn/matrix.c @@ -0,0 +1,78 @@ +#include "e.h" + +startcol(int type) /* mark start of column in lp[] array */ +{ + int oct = ct; + + lp[ct++] = type; + lp[ct++] = 0; /* count, to come */ + lp[ct++] = 0; /* separation, to come */ + return oct; +} + +void column(int oct, int sep) /* remember end of column that started at lp[oct] */ +{ + int i, type; + + lp[oct+1] = ct - oct - 3; + lp[oct+2] = sep; + type = lp[oct]; + if (dbg) { + printf(".\t%d column of", type); + for (i = oct+3; i < ct; i++ ) + printf(" S%d", lp[i]); + printf(", rows=%d, sep=%d\n", lp[oct+1], lp[oct+2]); + } +} + +void matrix(int oct) /* matrix is list of columns */ +{ + int nrow, ncol, i, j, k, val[100]; + double b, hb; + char *space; + extern char *Matspace; + + space = Matspace; /* between columns of matrix */ + nrow = lp[oct+1]; /* disaster if rows inconsistent */ + /* also assumes just columns */ + /* fix when add other things */ + ncol = 0; + for (i = oct+1; i < ct; i += lp[i]+3 ) { + ncol++; + dprintf(".\tcolct=%d\n", lp[i]); + } + for (k=1; k <= nrow; k++) { + hb = b = 0; + j = oct + k + 2; + for (i=0; i < ncol; i++) { + hb = max(hb, eht[lp[j]]-ebase[lp[j]]); + b = max(b, ebase[lp[j]]); + j += nrow + 3; + } + dprintf(".\trow %d: b=%g, hb=%g\n", k, b, hb); + j = oct + k + 2; + for (i=0; i\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2); + printf(".nr %d \\n(%d+%gm\n", treg, treg, Overwid); + d2 = eht[p2]-ebase[p2]-d; /* denom */ + printf(".ds %d \\v'%gm'\\h'\\n(%du-\\n(%du/2u'\\*(%d\\v'%gm'\\\n", + yyval, REL(d2,ps), treg, p2, p2, REL(-d2,ps)); + d1 = 2 * d + ebase[p1]; /* num */ + printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%gm'\\*(%d\\v'%gm'\\\n", + p2, p1, REL(-d1,ps), p1, REL(d1,ps)); + printf("\\h'-\\n(%du-\\n(%du/2u+%gm'\\v'%gm'\\l'\\n(%du-%gm'\\h'%gm'\\v'%gm'\n", + treg, p1, Overline, REL(-d,ps), + treg, 2*Overline, Overline, REL(d,ps)); + ebase[yyval] = b; + eht[yyval] = h; + lfont[yyval] = rfont[yyval] = 0; + sfree(p2); + sfree(treg); +} diff --git a/src/cmd/eqn/paren.c b/src/cmd/eqn/paren.c new file mode 100644 index 00000000..bb019bf7 --- /dev/null +++ b/src/cmd/eqn/paren.c @@ -0,0 +1,135 @@ +#include "e.h" + +#define abs(x) ((x) > 0 ? (x) : (-(x))) + +extern void brack(int, char *, char *, char *); + +void paren(int leftc, int p1, int rightc) +{ + int n, m, j; + double h1, b1; + double v, bv; /* v = shift of inside, bv = shift of brackets */ + extern double Parenbase, Parenshift, Parenheight; + + bv = ttype == DEVPOST ? Parenshift : 0; /* move brackets down this much */ + h1 = eht[p1]; + b1 = ebase[p1]; + yyval = p1; + lfont[yyval] = rfont[yyval] = 0; + n = REL(h1,ps) + 0.99; /* ceiling */ + 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] = EM((double) n + Parenheight, ps); + ebase[yyval] = eht[yyval]/2 - EM(Parenbase, ps); + + /* try to cope with things that are badly centered */ + /* (top heavy or bottom heavy) */ + if (abs(h1/2 - b1) >= EM(0.5, ps)) + v = REL(-ebase[yyval] + (eht[yyval]-h1)/2 + b1, ps); + else + v = 0; /* don't shift it at all */ + + printf(".ds %d \\^", yyval); /* was \| */ + if (bv) + printf("\\v'%gm'", bv); + 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; + } + if (bv) + printf("\\v'%gm'", -bv); + if (v) + printf("\\v'%gm'\\*(%d\\v'%gm'", -v, p1, v); + else + printf("\\*(%d", p1); + if (rightc) { + if (bv) + printf("\\v'%gm'", bv); + 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; + } + if (bv) + printf("\\v'%gm'", -bv); + } + printf("\n"); + dprintf(".\tcurly: h=%g b=%g n=%d v=%g l=%c, r=%c\n", + eht[yyval], ebase[yyval], n, v, leftc, rightc); +} + +void brack(int m, char *t, char *c, char *b) +{ + int j; + printf("\\b'%s", t); + for( j=0; j < m; j++) + printf("%s", c); + printf("%s'", b); +} diff --git a/src/cmd/eqn/pile.c b/src/cmd/eqn/pile.c new file mode 100644 index 00000000..a2d16239 --- /dev/null +++ b/src/cmd/eqn/pile.c @@ -0,0 +1,76 @@ +#include "e.h" +#include "y.tab.h" + +void pile(int oct) +{ + int i, nlist, nlist2, mid; + double bi, h, b, gap, sb; + extern double Pilegap, Pilebase; + int type, p1, p2; + + yyval = salloc(); + type = lp[oct]; + p1 = oct + 3; /* first entry */ + p2 = p1 + lp[oct+1]; /* 1 after last */ + gap = lp[oct+2]; + if (gap != DEFGAP) + gap = EM(gap/100.0, ps); + else if (type == COL) + gap = 0; + else + gap = EM(Pilegap, ps); /* 0.4 m between LCOL, etc. */ + 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 - EM(Pilebase, ps) - gap; + if (dbg) { + printf(".\tS%d <- %d pile of:", yyval, type); + for (i = p1; i < p2; i++) + printf(" S%d", lp[i]); + printf("; h=%g b=%g\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'%gm'\\h'%du*\\n(%du'\\\n", yyval, REL(ebase[yyval],ps), + type==RCOL ? 1 : 0, yyval); + sb = 0; /* sum of box hts */ + for (i = p2-1; i >= p1; i--) { + bi = sb + ebase[lp[i]]; + switch (type) { + case LCOL: + printf("\\v'%gm'\\*(%d\\h'-\\n(%du'\\v'%gm'\\\n", + REL(-bi,ps), lp[i], lp[i], REL(bi,ps)); + break; + case RCOL: + printf("\\v'%gm'\\h'-\\n(%du'\\*(%d\\v'%gm'\\\n", + REL(-bi,ps), lp[i], lp[i], REL(bi,ps)); + break; + case CCOL: + case COL: + printf("\\v'%gm'\\h'\\n(%du-\\n(%du/2u'\\*(%d", + REL(-bi,ps), yyval, lp[i], lp[i]); + printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%gm'\\\n", + yyval, lp[i], REL(bi,ps)); + break; + } + sb += eht[lp[i]] + gap; + } + printf("\\v'%gm'\\h'%du*\\n(%du'\n", REL(-ebase[yyval],ps), + type!=RCOL ? 1 : 0, yyval); + for (i = p1; i < p2; i++) + sfree(lp[i]); + lfont[yyval] = rfont[yyval] = 0; +} diff --git a/src/cmd/eqn/prevy.tab.h b/src/cmd/eqn/prevy.tab.h new file mode 100644 index 00000000..1f6d3c71 --- /dev/null +++ b/src/cmd/eqn/prevy.tab.h @@ -0,0 +1,57 @@ +#define CONTIG 57346 +#define QTEXT 57347 +#define SPACE 57348 +#define THIN 57349 +#define TAB 57350 +#define MATRIX 57351 +#define LCOL 57352 +#define CCOL 57353 +#define RCOL 57354 +#define COL 57355 +#define ABOVE 57356 +#define MARK 57357 +#define LINEUP 57358 +#define SUM 57359 +#define INT 57360 +#define PROD 57361 +#define UNION 57362 +#define INTER 57363 +#define DEFINE 57364 +#define TDEFINE 57365 +#define NDEFINE 57366 +#define DELIM 57367 +#define GSIZE 57368 +#define GFONT 57369 +#define INCLUDE 57370 +#define IFDEF 57371 +#define DOTEQ 57372 +#define DOTEN 57373 +#define FROM 57374 +#define TO 57375 +#define OVER 57376 +#define SQRT 57377 +#define SUP 57378 +#define SUB 57379 +#define SIZE 57380 +#define FONT 57381 +#define ROMAN 57382 +#define ITALIC 57383 +#define BOLD 57384 +#define FAT 57385 +#define UP 57386 +#define DOWN 57387 +#define BACK 57388 +#define FWD 57389 +#define LEFT 57390 +#define RIGHT 57391 +#define DOT 57392 +#define DOTDOT 57393 +#define HAT 57394 +#define TILDE 57395 +#define BAR 57396 +#define LOWBAR 57397 +#define HIGHBAR 57398 +#define UNDER 57399 +#define VEC 57400 +#define DYAD 57401 +#define UTILDE 57402 diff --git a/src/cmd/eqn/shift.c b/src/cmd/eqn/shift.c new file mode 100644 index 00000000..dbac530b --- /dev/null +++ b/src/cmd/eqn/shift.c @@ -0,0 +1,116 @@ +#include "e.h" +#include "y.tab.h" + +void subsup(int p1, int p2, int p3) +{ + if (p2 != 0 && p3 != 0) + shift2(p1, p2, p3); + else if (p2 != 0) + bshiftb(p1, SUB, p2); + else if (p3 != 0) + bshiftb(p1, SUP, p3); +} + +extern double Subbase, Supshift; +extern char *Sub1space, *Sup1space, *Sub2space; +extern char *SS1space, *SS2space; + +void bshiftb(int p1, int dir, int p2) +{ + int subps, n; + double shval, d1, h1, b1, h2, b2; + char *sh1, *sh2; + + yyval = p1; + h1 = eht[p1]; + b1 = ebase[p1]; + h2 = eht[p2]; + b2 = ebase[p2]; + subps = ps; + ps += deltaps; + if (dir == SUB) { + /* base .2m below bottom of main box */ + shval = b1 + EM(Subbase, ps); + ebase[yyval] = shval + b2; + eht[yyval] = max(h1-b1+shval+b2, h2); + if (rfont[p1] == ITAL && lfont[p2] == ROM) + n = 2; /* Sub1space */ + else + n = max(2, class[rclass[p1]][lclass[p2]]); + sh1 = pad(n); + rclass[p1] = OTHER; /* OTHER leaves too much after sup */ + } else { /* superscript */ + /* 4/10 up main box */ + d1 = EM(Subbase, subps); + ebase[yyval] = b1; + shval = -(Supshift * (h1-b1)) - b2; + if (Supshift*(h1-b1) + h2 < h1-b1) /* raise little super */ + shval = -(h1-b1) + h2-b2 - d1; + eht[yyval] = h1 + max(0, h2 - (1-Supshift)*(h1-b1)); + if (rclass[p1] == ILETF) + n = 4; + else if (rfont[p1] == ITAL) + n = 2; /* Sup1space */ + else + n = max(1, class[rclass[p1]][lclass[p2]]); + sh1 = pad(n); + rclass[p1] = rclass[p2]; /* OTHER leaves too much after sup */ + } + dprintf(".\tS%d <- %d shift %g %d; b=%g, h=%g, ps=%d, subps=%d\n", + yyval, p1, shval, p2, ebase[yyval], eht[yyval], ps, subps); + sh2 = Sub2space; /* was Sub2space; */ + printf(".as %d \\v'%gm'%s%s\\*(%d%s%s\\v'%gm'\n", + yyval, REL(shval,ps), DPS(ps,subps), sh1, p2, + DPS(subps,ps), sh2, REL(-shval,ps)); + rfont[p1] = 0; + sfree(p2); +} + +void shift2(int p1, int p2, int p3) +{ + int subps; + double h1, h2, h3, b1, b2, b3, subsh, d2, supsh; + int treg; + char *sh2; + + treg = salloc(); + yyval = p1; + subps = ps; /* sub and sup at this size */ + ps += deltaps; /* outer size */ + h1 = eht[p1]; b1 = ebase[p1]; + h2 = eht[p2]; b2 = ebase[p2]; + h3 = eht[p3]; b3 = ebase[p3]; + subsh = EM(Subbase, ps); + if (b1 > b2 + subsh) /* move little sub down */ + subsh += b1; + eht[yyval] = max(subsh+b2-b1+h1, h2); + supsh = -Supshift*(h1-b1) - b3; + d2 = EM(Subbase, subps); + if (h3 < (1-Supshift)*(h1-b1)) + supsh = -(h1-b1) + (h3-b3) - d2; + ebase[yyval] = subsh + b2 - b1; + eht[yyval] = h1 + subsh+b2-b1 + max(0, h3-(1-Supshift)*(h1-b1)); + dprintf(".\tS%d <- %d sub %d sup %d, ps=%d, subps=%d, h=%g, b=%g\n", + yyval, p1, p2, p3, ps, subps, eht[yyval], ebase[yyval]); + if (rclass[p1] == ILETF) + sh2 = "\\|\\|"; + else + sh2 = SS2space; + /*n = max(class[rclass[p1]][lclass[p2]], class[rclass[p1]][lclass[p3]]); + /*sh2 = pad(max(2, n)); + */ + printf(".ds %d %s\\*(%d\n", p2, SS1space, p2); + nrwid(p2, subps, p2); + printf(".ds %d %s\\*(%d\n", p3, sh2, p3); + nrwid(p3, subps, 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 %s\\v'%gm'\\*(%d\\v'%gm'\\h'-\\n(%du'\\\n", + p1, DPS(ps,subps), REL(subsh,subps), p2, REL(-subsh,subps), p2); + printf("\\v'%gm'\\*(%d\\v'%gm'\\h'-\\n(%du+\\n(%du'%s%s\n", + REL(supsh,subps), p3, REL(-supsh,subps), p3, treg, DPS(subps,ps), Sub2space); + if (rfont[p2] == ITAL) + rfont[yyval] = 0; /* lie */ + rclass[yyval] = rclass[p3]; /* was OTHER */ + sfree(p2); sfree(p3); sfree(treg); +} diff --git a/src/cmd/eqn/size.c b/src/cmd/eqn/size.c new file mode 100644 index 00000000..59bf3f20 --- /dev/null +++ b/src/cmd/eqn/size.c @@ -0,0 +1,70 @@ +#include "e.h" +#include + +void setsize(char *p) /* set size as found in p */ +{ + nszstack++; + szstack[nszstack] = 0; /* assume relative */ + if (*p == '+') { + ps += atoi(p+1); + if (szstack[nszstack-1] != 0) /* propagate absolute size */ + szstack[nszstack] = ps; + } else if (*p == '-') { + ps -= atoi(p+1); + if (szstack[nszstack-1] != 0) + szstack[nszstack] = ps; + } else if (isdigit(*p)) { + if (szstack[nszstack-1] == 0) + printf(".nr %d \\n(.s\n", 99-nszstack); + else + printf(".nr %d %d\n", 99-nszstack, ps); + szstack[nszstack] = ps = atoi(p); + } else { + ERROR "illegal size %s ignored", p WARNING; + } + dprintf(".\tsetsize %s; ps = %d\n", p, ps); +} + +void size(int p1, int p2) +{ + /* old size in p1, new in ps */ + yyval = p2; + dprintf(".\tS%d <- \\s%d %d \\s%d; b=%g, h=%g\n", + yyval, ps, p2, p1, ebase[yyval], eht[yyval]); + if (szstack[nszstack] != 0) { + printf(".ds %d %s\\*(%d\\s\\n(%d\n", yyval, ABSPS(ps), p2, 99-nszstack); + } else + printf(".ds %d %s\\*(%d%s\n", yyval, DPS(p1,ps), p2, DPS(ps,p1)); + nszstack--; + ps = p1; +} + +void globsize(void) +{ + char temp[20]; + + getstr(temp, sizeof(temp)); + if (temp[0] == '+') { + gsize += atoi(temp+1); + if (szstack[0] != 0) + szstack[0] = gsize; + } else if (temp[0] == '-') { + gsize -= atoi(temp+1); + if (szstack[0] != 0) + szstack[0] = gsize; + } else if (isdigit(temp[0])) { + gsize = atoi(temp); + szstack[0] = gsize; + printf(".nr 99 \\n(.s\n"); + } else { + ERROR "illegal gsize %s ignored", temp WARNING; + } + yyval = eqnreg = 0; + ps = gsize; + if (gsize < 12 && !dps_set) /* sub and sup size change */ + deltaps = gsize / 3; + else if (gsize < 20) + deltaps = gsize / 4; + else + deltaps = gsize / 5; +} diff --git a/src/cmd/eqn/sqrt.c b/src/cmd/eqn/sqrt.c new file mode 100644 index 00000000..391d924e --- /dev/null +++ b/src/cmd/eqn/sqrt.c @@ -0,0 +1,35 @@ +#include "e.h" + +void sqrt(int p2) +{ + static int af = 0; + int nps; /* point size for radical */ + double radscale = 0.95; + + if (ttype == DEVPOST) + radscale = 1.05; + nps = ps * radscale * eht[p2] / EM(1.0,ps) + 0.99; /* kludgy */ + nps = max(EFFPS(nps), ps); + yyval = p2; + if (ttype == DEVCAT || ttype == DEVAPS) + eht[yyval] = EM(1.2, nps); + else if (ttype == DEVPOST) + eht[yyval] = EM(1.15, nps); + else /* DEV202, DEVPOST */ + eht[yyval] = EM(1.15, nps); + dprintf(".\tS%d <- sqrt S%d;b=%g, h=%g, nps=%d\n", + yyval, p2, ebase[yyval], eht[yyval], nps); + printf(".as %d \\|\n", yyval); + nrwid(p2, ps, p2); + if (af++ == 0) + printf(".af 10 01\n"); /* make it two digits when it prints */ + printf(".nr 10 %.3fu*\\n(.su/10\n", 9.2*eht[p2]); /* this nonsense */ + /* guesses point size corresponding to height of stuff */ + printf(".ds %d \\v'%gm'\\s(\\n(10", yyval, REL(ebase[p2],ps)); + if (ttype == DEVCAT || ttype == DEVAPS) + printf("\\v'-.2m'\\(sr\\l'\\n(%du\\(rn'\\v'.2m'", p2); + else /* DEV202, DEVPOST so far */ + printf("\\(sr\\l'\\n(%du\\(rn'", p2); + printf("\\s0\\v'%gm'\\h'-\\n(%du'\\^\\*(%d\n", REL(-ebase[p2],ps), p2, p2); + lfont[yyval] = rfont[yyval] = ROM; +} diff --git a/src/cmd/eqn/text.c b/src/cmd/eqn/text.c new file mode 100644 index 00000000..261c7fbf --- /dev/null +++ b/src/cmd/eqn/text.c @@ -0,0 +1,318 @@ +#include "e.h" +#include "y.tab.h" +#include + +#define CSSIZE 1000 +char cs[CSSIZE+20]; /* text string converted into this */ +char *csp; /* next spot in cs[] */ +char *psp; /* next character in input token */ + +int lf, rf; /* temporary spots for left and right fonts */ +int lastft; /* last \f added */ +int nextft; /* next \f to be added */ + +int pclass; /* class of previous character */ +int nclass; /* class of next character */ + +int class[LAST][LAST] ={ /* guesswork, tuned to times roman postscript */ + + /*OT OL IL DG LP RP SL PL IF IJ VB */ +/*OT*/ { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0 }, /* OTHER */ +/*OL*/ { 1, 0, 1, 1, 1, 1, 1, 2, 2, 2, 0 }, /* OLET */ +/*IL*/ { 1, 1, 0, 1, 1, 1, 1, 3, 2, 1, 0 }, /* ILET */ +/*DG*/ { 1, 1, 1, 0, 1, 1, 1, 2, 2, 2, 0 }, /* DIG */ +/*LP*/ { 1, 1, 1, 1, 1, 2, 1, 2, 3, 3, 0 }, /* LPAR */ +/*RP*/ { 2, 2, 2, 1, 1, 1, 1, 2, 3, 3, 0 }, /* RPAR */ +/*SL*/ { 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0 }, /* SLASH */ +/*PL*/ { 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 0 }, /* PLUS */ +/*IF*/ { 3, 3, 1, 2, 2, 3, 2, 3, 0, 1, 1 }, /* ILETF */ +/*IJ*/ { 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0 }, /* ILETJ */ +/*VB*/ { 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 1 }, /* VBAR */ + +}; + +extern void shim(int, int); +extern void roman(int); +extern void sadd(char *); +extern void cadd(int); +extern int trans(int, char *); + +int textc(void) /* read next UTF rune from psp */ +{ + wchar_t r; + int w; + + w = mbtowc(&r, psp, 3); + if(w == 0){ + psp++; + return 0; + } + if(w < 0){ + psp += 1; + return 0x80; /* Plan 9-ism */ + } + psp += w; + return r; +} + +void text(int t, char *p1) /* convert text string p1 of type t */ +{ + int c; + char *p; + tbl *tp; + + yyval = salloc(); + ebase[yyval] = 0; + eht[yyval] = EM(1.0, ps); /* ht in ems of orig size */ + lfont[yyval] = rfont[yyval] = ROM; + lclass[yyval] = rclass[yyval] = OTHER; + if (t == QTEXT) { + for (p = p1; *p; p++) /* scan for embedded \f's */ + if (*p == '\\' && *(p+1) == 'f') + break; + if (*p) /* if found \f, leave it alone and hope */ + p = p1; + else { + sprintf(cs, "\\f%s%s\\fP", ftp->name, p1); + p = cs; + } + } else if (t == SPACE) + p = "\\ "; + else if (t == THIN) + p = "\\|"; + else if (t == TAB) + p = "\\t"; + else if ((tp = lookup(restbl, p1)) != NULL) { + p = tp->cval; + } else { + lf = rf = 0; + lastft = 0; + nclass = NONE; /* get started with no class == no pad */ + csp = cs; + for (psp = p1; (c = textc()) != '\0'; ) { + nextft = ft; + pclass = nclass; + rf = trans(c, p1); + if (lf == 0) { + lf = rf; /* left stuff is first found */ + lclass[yyval] = nclass; + } + if (csp-cs > CSSIZE) + ERROR "converted token %.25s... too long", p1 FATAL ; + } + sadd("\\fP"); + *csp = '\0'; + p = cs; + lfont[yyval] = lf; + rfont[yyval] = rf; + rclass[yyval] = nclass; + } + dprintf(".\t%dtext: S%d <- %s; b=%g,h=%g,lf=%c,rf=%c,ps=%d\n", + t, yyval, p, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval], ps); + printf(".ds %d \"%s\n", yyval, p); +} + +int isalpharune(int c) +{ + return ('a'<=c && c<='z') || ('A'<=c && c<='Z'); +} + +int isdigitrune(int c) +{ + return ('0'<=c && c<='9'); +} + +trans(int c, char *p1) +{ + int f; + + if (isalpharune(c) && ft == ITAL && c != 'f' && c != 'j') { /* italic letter */ + shim(pclass, nclass = ILET); + cadd(c); + return ITAL; + } + if (isalpharune(c) && ft != ITAL) { /* other letter */ + shim(pclass, nclass = OLET); + cadd(c); + return ROM; + } + if (isdigitrune(c)) { + shim(pclass, nclass = DIG); + roman(c); + return ROM; /* this is the right side font of this object */ + } + f = ROM; + nclass = OTHER; + switch (c) { + case ':': case ';': case '!': case '%': case '?': + shim(pclass, nclass); + roman(c); + return f; + case '(': case '[': + shim(pclass, nclass = LPAR); + roman(c); + return f; + case ')': case ']': + shim(pclass, nclass = RPAR); + roman(c); + return f; + case ',': + shim(pclass, nclass = OTHER); + roman(c); + return f; + case '.': + if (rf == ROM) + roman(c); + else + cadd(c); + return f; + case '|': /* postscript needs help with default width! */ + shim(pclass, nclass = VBAR); + sadd("\\v'.17m'\\z|\\v'-.17m'\\|"); /* and height */ + return f; + case '=': + shim(pclass, nclass = PLUS); + sadd("\\(eq"); + return f; + case '+': + shim(pclass, nclass = PLUS); + sadd("\\(pl"); + return f; + case '>': + case '<': /* >, >=, >>, <, <-, <=, << */ + shim(pclass, nclass = PLUS); + if (*psp == '=') { + sadd(c == '<' ? "\\(<=" : "\\(>="); + psp++; + } else if (c == '<' && *psp == '-') { /* <- only */ + sadd("\\(<-"); + psp++; + } else if (*psp == c) { /* << or >> */ + cadd(c); + cadd(c); + psp++; + } else { + cadd(c); + } + return f; + case '-': + shim(pclass, nclass = PLUS); /* probably too big for ->'s */ + if (*psp == '>') { + sadd("\\(->"); + psp++; + } else { + sadd("\\(mi"); + } + return f; + case '/': + shim(pclass, nclass = SLASH); + cadd('/'); + return f; + case '~': + case ' ': + sadd("\\|\\|"); + return f; + case '^': + sadd("\\|"); + return f; + case '\\': /* troff - pass only \(xx without comment */ + shim(pclass, nclass); + cadd('\\'); + cadd(c = *psp++); + if (c == '(' && *psp && *(psp+1)) { + cadd(*psp++); + cadd(*psp++); + } else + fprintf(stderr, "eqn warning: unquoted troff command \\%c, file %s:%d\n", + c, curfile->fname, curfile->lineno); + return f; + case '\'': + shim(pclass, nclass); + sadd("\\(fm"); + return f; + + case 'f': + if (ft == ITAL) { + shim(pclass, nclass = ILETF); + cadd('f'); + f = ITAL; + } else + cadd('f'); + return f; + case 'j': + if (ft == ITAL) { + shim(pclass, nclass = ILETJ); + cadd('j'); + f = ITAL; + } else + cadd('j'); + return f; + default: + shim(pclass, nclass); + cadd(c); + return ft==ITAL ? ITAL : ROM; + } +} + +char *pad(int n) /* return the padding as a string */ +{ + static char buf[20]; + + buf[0] = 0; + if (n < 0) { + sprintf(buf, "\\h'-%du*\\w'\\^'u'", -n); + return buf; + } + for ( ; n > 1; n -= 2) + strcat(buf, "\\|"); + if (n > 0) + strcat(buf, "\\^"); + return buf; +} + +void shim(int lc, int rc) /* add padding space suitable to left and right classes */ +{ + sadd(pad(class[lc][rc])); +} + +void roman(int c) /* add char c in "roman" font */ +{ + nextft = ROM; + cadd(c); +} + +void sadd(char *s) /* add string s to cs */ +{ + while (*s) + cadd(*s++); +} + +void cadd(int c) /* add character c to end of cs */ +{ + char *p; + int w; + + if (lastft != nextft) { + if (lastft != 0) { + *csp++ = '\\'; + *csp++ = 'f'; + *csp++ = 'P'; + } + *csp++ = '\\'; + *csp++ = 'f'; + if (ftp == ftstack) { /* bottom level */ + if (ftp->ft == ITAL) /* usual case */ + *csp++ = nextft; + else /* gfont set, use it */ + for (p = ftp->name; *csp = *p++; ) + csp++; + } else { /* inside some kind of font ... */ + for (p = ftp->name; *csp = *p++; ) + csp++; + } + lastft = nextft; + } + w = wctomb(csp, c); + if(w > 0) /* ignore bad characters */ + csp += w; +} diff --git a/src/cmd/eqn/tuning.c b/src/cmd/eqn/tuning.c new file mode 100644 index 00000000..99718db3 --- /dev/null +++ b/src/cmd/eqn/tuning.c @@ -0,0 +1,153 @@ +#include "e.h" + +/* + +This file contains parameter values for many of the +tuning parameters in eqn. Names are defined words. + +Strings are plugged in verbatim. +Floats are usually in ems. + +*/ + +/* In main.c: */ + +double BeforeSub = 1.2; /* line space before a subscript */ +double AfterSub = 0.2; /* line space after a subscript */ + +/* diacrit.c: */ + +double Dvshift = 0.25; /* vertical shift for diacriticals on tall letters */ +double Dhshift = 0.025; /* horizontal shift for tall letters */ +double Dh2shift = 0.05; /* horizontal shift for small letters */ +double Dheight = 0.25; /* increment to height for diacriticals */ +double Barv = 0.68; /* vertical shift for bar */ +double Barh = 0.05; /* 1/2 horizontal shrink for bar */ +double Ubarv = 0.1; /* shift underbar up this much ems */ +double Ubarh = 0.05; /* 1/2 horizontal shrink for underbar */ + +/* Also: + Vec, Dyad, Hat, Tilde, Dot, Dotdot, Utilde */ + +/* eqnbox.c: */ + +char *IRspace = "\\^"; /* space between italic & roman boxes */ + +/* fat.c: */ + +double Fatshift = 0.05; /* fattening shifts by Fatshift ems */ + +/* funny.c: */ + +int Funnyps = 5; /* point size change (== 5 above) */ +double Funnyht = 0.2; /* height correction */ +double Funnybase = 0.3; /* base correction */ + +/* integral.c: */ + +int Intps = 4; /* point size change for integral (== 4 above) */ +double Intht = 1.15; /* ht of integral in ems */ +double Intbase = 0.3; /* base in ems */ +double Int1h = 0.4; /* lower limit left */ +double Int1v = 0.2; /* lower limit down */ +double Int2h = 0.05; /* upper limit right was 8 */ +double Int2v = 0.1; /* upper limit up */ + +/* matrix.c: */ + +char *Matspace = "\\ \\ "; /* space between matrix columns */ + +/* over.c: */ + +double Overgap = 0.3; /* gap between num and denom */ +double Overwid = 0.5; /* extra width of box */ +double Overline = 0.1; /* extra length of fraction bar */ + +/* paren.c* */ + +double Parenbase = 0.4; /* shift of base for even count */ +double Parenshift = 0.13; /* how much to shift parens down in left ... */ + /* ignored unless postscript */ +double Parenheight = 0.3; /* extra height above builtups */ + +/* pile.c: */ + +double Pilegap = 0.4; /* gap between pile elems */ +double Pilebase = 0.5; /* shift base of even # of piled elems */ + +/* shift.c: */ + +double Subbase = 0.2; /* subscript base belowe main base */ +double Supshift = 0.4; /* superscript .4 up main box */ +char *Sub1space = "\\|"; /* italic sub roman space */ +char *Sup1space = "\\|"; /* italic sup roman space */ +char *Sub2space = "\\^"; /* space after subscripted thing */ +char *SS1space = "\\^"; /* space before sub in x sub i sup j */ +char *SS2space = "\\^"; /* space before sup */ + +/* sqrt.c: */ + /* sqrt is hard! punt for now. */ + /* part of the problem is that every typesetter does it differently */ + /* and we have several typesetters to run. */ + +/* text.c: */ + /* ought to be done by a table */ + +struct tune { + char *name; + char *cval; +} tune[] ={ + /* diacrit.c */ + "vec_def", "\\f1\\v'-.5m'\\s-3\\(->\\s0\\v'.5m'\\fP", /* was \s-2 & .45m */ + "dyad_def", "\\f1\\v'-.5m'\\s-3\\z\\(<-\\|\\(->\\s0\\v'.5m'\\fP", + "hat_def", "\\f1\\v'-.05m'\\s+1^\\s0\\v'.05m'\\fP", /* was .1 */ + "tilde_def", "\\f1\\v'-.05m'\\s+1~\\s0\\v'.05m'\\fP", + "dot_def", "\\f1\\v'-.67m'.\\v'.67m'\\fP", + "dotdot_def", "\\f1\\v'-.67m'..\\v'.67m'\\fP", + "utilde_def", "\\f1\\v'1.0m'\\s+2~\\s-2\\v'-1.0m'\\fP", + /* funny.c */ + "sum_def", "\\|\\v'.3m'\\s+5\\(*S\\s-5\\v'-.3m'\\|", + "union_def", "\\|\\v'.3m'\\s+5\\(cu\\s-5\\v'-.3m'\\|", + "inter_def", "\\|\\v'.3m'\\s+5\\(ca\\s-5\\v'-.3m'\\|", + "prod_def", "\\|\\v'.3m'\\s+5\\(*P\\s-5\\v'-.3m'\\|", + /* integral.c */ + "int_def", "\\v'.1m'\\s+4\\(is\\s-4\\v'-.1m'", + 0, 0 +}; + +tbl *ftunetbl[TBLSIZE]; /* user-defined names */ + +char *ftunes[] ={ /* this table intentionally left small */ + "Subbase", + "Supshift", + 0 +}; + +void init_tune(void) +{ + int i; + + for (i = 0; tune[i].name != NULL; i++) + install(deftbl, tune[i].name, tune[i].cval, 0); + for (i = 0; ftunes[i] != NULL; i++) + install(ftunetbl, ftunes[i], (char *) 0, 0); +} + +#define eq(s, t) (strcmp(s,t) == 0) + +void ftune(char *s, char *t) /* brute force for now */ +{ + double f = atof(t); + double *target; + + while (*t == ' ' || *t == '\t') + t++; + if (eq(s, "Subbase")) + target = &Subbase; + else if (eq(s, "Supshift")) + target = &Supshift; + if (t[0] == '+' || t[0] == '-') + *target += f; + else + *target = f; +} diff --git a/src/cmd/eqn/y.tab.h b/src/cmd/eqn/y.tab.h new file mode 100644 index 00000000..1f6d3c71 --- /dev/null +++ b/src/cmd/eqn/y.tab.h @@ -0,0 +1,57 @@ +#define CONTIG 57346 +#define QTEXT 57347 +#define SPACE 57348 +#define THIN 57349 +#define TAB 57350 +#define MATRIX 57351 +#define LCOL 57352 +#define CCOL 57353 +#define RCOL 57354 +#define COL 57355 +#define ABOVE 57356 +#define MARK 57357 +#define LINEUP 57358 +#define SUM 57359 +#define INT 57360 +#define PROD 57361 +#define UNION 57362 +#define INTER 57363 +#define DEFINE 57364 +#define TDEFINE 57365 +#define NDEFINE 57366 +#define DELIM 57367 +#define GSIZE 57368 +#define GFONT 57369 +#define INCLUDE 57370 +#define IFDEF 57371 +#define DOTEQ 57372 +#define DOTEN 57373 +#define FROM 57374 +#define TO 57375 +#define OVER 57376 +#define SQRT 57377 +#define SUP 57378 +#define SUB 57379 +#define SIZE 57380 +#define FONT 57381 +#define ROMAN 57382 +#define ITALIC 57383 +#define BOLD 57384 +#define FAT 57385 +#define UP 57386 +#define DOWN 57387 +#define BACK 57388 +#define FWD 57389 +#define LEFT 57390 +#define RIGHT 57391 +#define DOT 57392 +#define DOTDOT 57393 +#define HAT 57394 +#define TILDE 57395 +#define BAR 57396 +#define LOWBAR 57397 +#define HIGHBAR 57398 +#define UNDER 57399 +#define VEC 57400 +#define DYAD 57401 +#define UTILDE 57402 -- cgit v1.2.3