Let's try this. It's BUGGERED.

This commit is contained in:
rsc 2004-05-15 23:24:00 +00:00
parent 76e6aca867
commit 5cedca1b69
118 changed files with 26947 additions and 1 deletions

75
src/cmd/eqn/diacrit.c Normal file
View file

@ -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);
}

166
src/cmd/eqn/e.h Normal file
View file

@ -0,0 +1,166 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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);

741
src/cmd/eqn/eqn.c Normal file
View file

@ -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 */
}

140
src/cmd/eqn/eqn.y Normal file
View file

@ -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
;
%%

24
src/cmd/eqn/eqnbox.c Normal file
View file

@ -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);
}

70
src/cmd/eqn/font.c Normal file
View file

@ -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);
}

52
src/cmd/eqn/fromto.c Normal file
View file

@ -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);
}

30
src/cmd/eqn/funny.c Normal file
View file

@ -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;
}

35
src/cmd/eqn/glob.c Normal file
View file

@ -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 */

289
src/cmd/eqn/input.c Normal file
View file

@ -0,0 +1,289 @@
#include "e.h"
#include "y.tab.h"
#include <ctype.h>
#include <errno.h>
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;
}

30
src/cmd/eqn/integral.c Normal file
View file

@ -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;
}

265
src/cmd/eqn/lex.c Normal file
View file

@ -0,0 +1,265 @@
#include "e.h"
#include "y.tab.h"
#include <ctype.h>
#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';
}

219
src/cmd/eqn/lookup.c Normal file
View file

@ -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 */
}

333
src/cmd/eqn/main.c Normal file
View file

@ -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;
}

19
src/cmd/eqn/mark.c Normal file
View file

@ -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);
}

78
src/cmd/eqn/matrix.c Normal file
View file

@ -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<ncol; i++) {
ebase[lp[j]] = b;
eht[lp[j]] = b + hb;
j += nrow + 3;
}
}
j = oct;
for (i=0; i<ncol; i++) {
pile(j);
val[i] = yyval;
j += nrow + 3;
}
yyval = salloc();
eht[yyval] = eht[val[0]];
ebase[yyval] = ebase[val[0]];
lfont[yyval] = rfont[yyval] = 0;
dprintf(".\tmatrix S%d: r=%d, c=%d, h=%g, b=%g\n",
yyval,nrow,ncol,eht[yyval],ebase[yyval]);
printf(".ds %d \"", yyval);
for( i=0; i<ncol; i++ ) {
printf("\\*(%d%s", val[i], i==ncol-1 ? "" : space);
sfree(val[i]);
}
printf("\n");
}

42
src/cmd/eqn/mkfile Normal file
View file

@ -0,0 +1,42 @@
<$PLAN9/src/mkhdr
TARG=eqn
OFILES=main.$O\
tuning.$O\
diacrit.$O\
eqnbox.$O\
font.$O\
fromto.$O\
funny.$O\
glob.$O\
integral.$O\
input.$O\
lex.$O\
lookup.$O\
mark.$O\
matrix.$O\
move.$O\
over.$O\
paren.$O\
pile.$O\
shift.$O\
size.$O\
sqrt.$O\
text.$O\
eqn.$O\
YFILES=eqn.y\
HFILES=e.h\
y.tab.h\
SHORTLIB=bio 9
<$PLAN9/src/mkone
YFLAGS=-d -S
eqn.c: y.tab.c prevy.tab.h
mv y.tab.c $target
prevy.tab.h: y.tab.h
sh -c 'cmp -s y.tab.h prevy.tab.h || cp y.tab.h prevy.tab.h'

19
src/cmd/eqn/move.c Normal file
View file

@ -0,0 +1,19 @@
# include "e.h"
# include "y.tab.h"
void move(int dir, int amt, int p)
{
double a;
yyval = p;
a = EM(amt/100.0, ps);
printf(".ds %d ", yyval);
if (dir == FWD || dir == BACK)
printf("\\h'%s%gm'\\*(%d\n", (dir==BACK) ? "-" : "", a, p);
else if (dir == UP)
printf("\\v'-%gm'\\*(%d\\v'%gm'\n", a, p, a);
else if (dir == DOWN)
printf("\\v'%gm'\\*(%d\\v'-%gm'\n", a, p, a);
dprintf(".\tmove %d dir %d amt %g; h=%g b=%g\n",
p, dir, a, eht[yyval], ebase[yyval]);
}

BIN
src/cmd/eqn/o.eqn Executable file

Binary file not shown.

35
src/cmd/eqn/over.c Normal file
View file

@ -0,0 +1,35 @@
#include "e.h"
void boverb(int p1, int p2)
{
int treg;
double h, b, d, d1, d2;
extern double Overgap, Overwid, Overline;
treg = salloc();
yyval = p1;
d = EM(Overgap, ps);
h = eht[p1] + eht[p2] + d;
b = eht[p2] - d;
dprintf(".\tS%d <- %d over %d; b=%g, h=%g\n",
yyval, p1, p2, b, h);
nrwid(p1, ps, p1);
nrwid(p2, ps, p2);
printf(".nr %d \\n(%d\n", treg, p1);
printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2);
printf(".nr %d \\n(%d+%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);
}

135
src/cmd/eqn/paren.c Normal file
View file

@ -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);
}

76
src/cmd/eqn/pile.c Normal file
View file

@ -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;
}

57
src/cmd/eqn/prevy.tab.h Normal file
View file

@ -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

116
src/cmd/eqn/shift.c Normal file
View file

@ -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);
}

70
src/cmd/eqn/size.c Normal file
View file

@ -0,0 +1,70 @@
#include "e.h"
#include <ctype.h>
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;
}

35
src/cmd/eqn/sqrt.c Normal file
View file

@ -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;
}

318
src/cmd/eqn/text.c Normal file
View file

@ -0,0 +1,318 @@
#include "e.h"
#include "y.tab.h"
#include <ctype.h>
#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;
}

153
src/cmd/eqn/tuning.c Normal file
View file

@ -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;
}

57
src/cmd/eqn/y.tab.h Normal file
View file

@ -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