eqn: pass the message as a string to fprintf in errdie
[neateqn.git] / def.c
blobdcf147483dc9e3f4a94d7c97acb494bead1cfce7
1 #include <stdio.h>
2 #include <string.h>
3 #include "eqn.h"
5 /* null-terminated list of default macros */
6 char *def_macros[][2] = {
7 {"<-", "\\(<-"},
8 {"<=", "\\(<="},
9 {">=", "\\(>="},
10 {"==", "\\(=="},
11 {"->", "\\(->"},
12 {"!=", "\\(!="},
13 {"+-", "\\(+-"},
14 {"...", "vcenter roman \"\\ .\\ .\\ .\\ \""},
15 {",...,", "roman \",\\ .\\ .\\ .\\ ,\\|\""},
16 {"ALPHA", "\\(*A"},
17 {"BETA", "\\(*B"},
18 {"CHI", "\\(*X"},
19 {"DELTA", "\\(*D"},
20 {"EPSILON", "\\(*E"},
21 {"ETA", "\\(*Y"},
22 {"GAMMA", "\\(*G"},
23 {"IOTA", "\\(*I"},
24 {"KAPPA", "\\(*K"},
25 {"LAMBDA", "\\(*L"},
26 {"MU", "\\(*M"},
27 {"NU", "\\(*N"},
28 {"OMEGA", "\\(*W"},
29 {"OMICRON", "\\(*O"},
30 {"PHI", "\\(*F"},
31 {"PI", "\\(*P"},
32 {"PSI", "\\(*Q"},
33 {"RHO", "\\(*R"},
34 {"SIGMA", "\\(*S"},
35 {"TAU", "\\(*T"},
36 {"THETA", "\\(*H"},
37 {"UPSILON", "\\(*U"},
38 {"XI", "\\(*C"},
39 {"ZETA", "\\(*Z"},
40 {"alpha", "\\(*a"},
41 {"beta", "\\(*b"},
42 {"chi", "\\(*x"},
43 {"delta", "\\(*d"},
44 {"epsilon", "\\(*e"},
45 {"eta", "\\(*y"},
46 {"gamma", "\\(*g"},
47 {"iota", "\\(*i"},
48 {"kappa", "\\(*k"},
49 {"lambda", "\\(*l"},
50 {"mu", "\\(*m"},
51 {"nu", "\\(*n"},
52 {"omega", "\\(*w"},
53 {"omicron", "\\(*o"},
54 {"phi", "\\(*f"},
55 {"pi", "\\(*p"},
56 {"psi", "\\(*q"},
57 {"rho", "\\(*r"},
58 {"sigma", "\\(*s"},
59 {"tau", "\\(*t"},
60 {"theta", "\\(*h"},
61 {"upsilon", "\\(*u"},
62 {"xi", "\\(*c"},
63 {"zeta", "\\(*z"},
64 {"Im", "roman \"Im\""},
65 {"Re", "roman \"Re\""},
66 {"and", "roman \"and\""},
67 {"approx", "\"\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'\""},
68 {"arc", "roman \"arc\""},
69 {"cdot", "\\(c."},
70 {"cos", "roman \"cos\""},
71 {"cosh", "roman \"cosh\""},
72 {"coth", "roman \"coth\""},
73 {"del", "\\(gr"},
74 {"det", "roman \"det\""},
75 {"dollar", "roman $"},
76 {"exp", "roman \"exp\""},
77 {"for", "roman \"for\""},
78 {"grad", "\\(gr"},
79 {"half", "roman \\(12"},
80 {"if", "roman \"if\""},
81 {"inf", "\\(if"},
82 {"infinity", "\\(if"},
83 {"int", "{vcenter roman size +2 \\(is}"},
84 {"inter", "roman size +2 \\(ca"},
85 {"lim", "roman \"lim\""},
86 {"ln", "roman \"ln\""},
87 {"log", "roman \"log\""},
88 {"max", "roman \"max\""},
89 {"min", "roman \"min\""},
90 {"nothing", ""},
91 {"partial", "\\(pd"},
92 {"prime", "roman \\(fm"},
93 {"prod", "{vcenter roman size +2 \\(pr}"},
94 {"sin", "roman \"sin\""},
95 {"sinh", "roman \"sinh\""},
96 {"sum", "{vcenter roman size +2 \\(su}"},
97 {"tan", "roman \"tan\""},
98 {"tanh", "roman \"tanh\""},
99 {"times", "\\(mu"},
100 {"union", "roman size +2 \\(cu"},
101 {NULL, NULL}
104 /* list of binary operations */
105 static char *binops[] = {
106 "+", "\\(pl",
107 "−", "-", "\\(mi",
108 "÷", "\\(-:", "\\(di",
109 "×", "xx", "\\(mu",
110 "±", "\\(+-",
111 "⊗", "\\(Ox",
112 "⊕", "\\(O+",
113 "∧", "\\(l&",
114 "∨", "\\(l|",
115 "∩", "\\(ca",
116 "∪", "\\(cu",
117 "⋅", "\\(c.",
120 /* list of relations */
121 static char *relops[] = {
122 "<", ">", ":=",
123 "=", "\\(eq",
124 "≅", "\\(cg",
125 "≤", "\\(<=",
126 "≥", "\\(>=",
127 "≠", "\\(!=",
128 "≡", "\\(==",
129 "≈", "\\(~~",
130 "⊃", "\\(sp",
131 "⊇", "\\(ip",
132 "⊄", "\\(!b",
133 "⊂", "\\(sb",
134 "⊆", "\\(ib",
135 "∈", "\\(mo",
136 "∉", "\\(!m",
137 "↔", "\\(ab",
138 "←", "\\(<-",
139 "↑", "\\(ua",
140 "→", "\\(->",
141 "↓", "\\(da",
144 /* list of punctuations */
145 static char *puncs[] = {".", ",", ";", ":", "!"};
147 /* left and right brackets */
148 static char *bracketleft[] = {"(", "[", "{", "\\(lc", "\\(lf", "\\(la"};
149 static char *bracketright[] = {")", "]", "}", "\\(rc", "\\(rf", "\\(ra"};
151 /* glyphs for different bracket sizes */
152 static char bracketsizes[32][NSIZES][BRLEN] = {
153 {"(", "(", "\\N'parenleftbig'", "\\N'parenleftBig'",
154 "\\N'parenleftbigg'", "\\N'parenleftBigg'"},
155 {")", ")", "\\N'parenrightbig'", "\\N'parenrightBig'",
156 "\\N'parenrightbigg'", "\\N'parenrightBigg'"},
157 {"[", "[", "\\N'bracketleftbig'", "\\N'bracketleftBig'",
158 "\\N'bracketleftbigg'", "\\N'bracketleftBigg'"},
159 {"]", "]", "\\N'bracketrightbig'", "\\N'bracketrightBig'",
160 "\\N'bracketrightbigg'", "\\N'bracketrightBigg'"},
161 {"{", "{", "\\N'braceleftbig'", "\\N'braceleftBig'",
162 "\\N'braceleftbigg'", "\\N'braceleftBigg'"},
163 {"}", "}", "\\N'bracerightbig'", "\\N'bracerightBig'",
164 "\\N'bracerightbigg'", "\\N'bracerightBigg'"},
165 {"\\(lc", "\\N'ceilingleft'", "\\N'ceilingleftbig'", "\\N'ceilingleftBig'",
166 "\\N'ceilingleftbigg'", "\\N'ceilingleftBigg'", "\\(lc"},
167 {"\\(rc", "\\N'ceilingright'", "\\N'ceilingrightbig'", "\\N'ceilingrightBig'",
168 "\\N'ceilingrightbigg'", "\\N'ceilingrightBigg'", "\\(rc"},
169 {"\\(lf", "\\N'floorleft'", "\\N'floorleftbig'", "\\N'floorleftBig'",
170 "\\N'floorleftbigg'", "\\N'floorleftBigg'", "\\(lf"},
171 {"\\(rf", "\\N'floorright'", "\\N'floorrightbig'", "\\N'floorrightBig'",
172 "\\N'floorrightbigg'", "\\N'floorrightBigg'", "\\(rf"},
173 {"\\(la", "\\(la", "\\N'angbracketleft'", "\\N'angbracketleftbig'",
174 "\\N'angbracketleftBig'", "\\N'angbracketleftbigg'", "\\N'angbracketleftBigg'"},
175 {"\\(ra", "\\(ra", "\\N'angbracketright'", "\\N'angbracketrightbig'",
176 "\\N'angbracketrightBig'", "\\N'angbracketrightbigg'", "\\N'angbracketrightBigg'"},
177 {"|", "|", "|", "|", "|"},
178 {"\\(sr", "\\(sr", "\\N'radical'", "\\N'radicalbig'", "\\N'radicalBig'",
179 "\\N'radicalbigg'", "\\N'radicalBigg'"},
182 /* large glyph pieces: name, top, mid, bot, centre */
183 static char bracketpieces[32][8][BRLEN] = {
184 {"(", "\\(LT", "\\(LX", "\\(LB"},
185 {")", "\\(RT", "\\(RX", "\\(RB"},
186 {"[", "\\(lc", "\\(lx", "\\(lf"},
187 {"]", "\\(rc", "\\(rx", "\\(rf"},
188 {"{", "\\(lt", "\\(bv", "\\(lb", "\\(lk"},
189 {"}", "\\(rt", "\\(bv", "\\(rb", "\\(rk"},
190 {"\\(lc", "\\(lc", "\\(lx", "\\(lx"},
191 {"\\(rc", "\\(rc", "\\(rx", "\\(rx"},
192 {"\\(lf", "\\(lx", "\\(lx", "\\(lf"},
193 {"\\(rf", "\\(rx", "\\(rx", "\\(rf"},
194 {"|", "|", "|", "|"},
195 {"\\(sr", "\\N'radicaltp'", "\\N'radicalvertex'", "\\N'radicalbt'"},
198 /* custom glyph types */
199 static struct gtype {
200 char g[GNLEN];
201 int type;
202 } gtypes[128];
204 void def_typeput(char *s, int type)
206 int i;
207 for (i = 0; i < LEN(gtypes) && gtypes[i].g[0]; i++)
208 if (!strcmp(s, gtypes[i].g))
209 break;
210 if (i < LEN(gtypes)) {
211 strcpy(gtypes[i].g, s);
212 gtypes[i].type = type;
216 /* find an entry in an array */
217 static char *alookup(char **a, int len, char *s)
219 int i;
220 for (i = 0; i < len; i++)
221 if (!strcmp(s, a[i]))
222 return a[i];
223 return NULL;
226 int def_type(char *s)
228 int i;
229 for (i = 0; i < LEN(gtypes) && gtypes[i].g[0]; i++)
230 if (!strcmp(s, gtypes[i].g))
231 return gtypes[i].type;
232 if (alookup(puncs, LEN(puncs), s))
233 return T_PUNC;
234 if (alookup(binops, LEN(binops), s))
235 return T_BINOP;
236 if (alookup(relops, LEN(relops), s))
237 return T_RELOP;
238 if (alookup(bracketleft, LEN(bracketleft), s))
239 return T_LEFT;
240 if (alookup(bracketright, LEN(bracketright), s))
241 return T_RIGHT;
242 return -1;
245 static int pieces_find(char *sign)
247 int i;
248 for (i = 0; i < LEN(bracketpieces); i++)
249 if (!strcmp(bracketpieces[i][0], sign))
250 return i;
251 return -1;
254 /* find the pieces for creating the given bracket */
255 void def_pieces(char *sign, char **top, char **mid, char **bot, char **cen)
257 int i = pieces_find(sign);
258 if (i >= 0) {
259 *top = bracketpieces[i][1][0] ? bracketpieces[i][1] : NULL;
260 *mid = bracketpieces[i][2][0] ? bracketpieces[i][2] : NULL;
261 *bot = bracketpieces[i][3][0] ? bracketpieces[i][3] : NULL;
262 *cen = bracketpieces[i][4][0] ? bracketpieces[i][4] : NULL;
266 void def_piecesput(char *sign, char *top, char *mid, char *bot, char *cen)
268 int i = pieces_find(sign);
269 if (i < 0 && (i = pieces_find("")) < 0)
270 return;
271 snprintf(bracketpieces[i][0], sizeof(bracketpieces[i][0]), "%s", sign);
272 snprintf(bracketpieces[i][1], sizeof(bracketpieces[i][1]), "%s", top);
273 snprintf(bracketpieces[i][2], sizeof(bracketpieces[i][2]), "%s", mid);
274 snprintf(bracketpieces[i][3], sizeof(bracketpieces[i][3]), "%s", bot);
275 snprintf(bracketpieces[i][4], sizeof(bracketpieces[i][4]), "%s", cen);
278 static int sizes_find(char *sign)
280 int i;
281 for (i = 0; i < LEN(bracketsizes); i++)
282 if (!strcmp(bracketsizes[i][0], sign))
283 return i;
284 return -1;
287 /* return different sizes of the given bracket */
288 void def_sizes(char *sign, char *sizes[])
290 int idx = sizes_find(sign);
291 int i;
292 sizes[0] = sign;
293 for (i = 1; idx >= 0 && i < NSIZES; i++)
294 sizes[i - 1] = bracketsizes[idx][i][0] ? bracketsizes[idx][i] : NULL;
297 void def_sizesput(char *sign, char *sizes[])
299 int idx = sizes_find(sign);
300 int i;
301 if (idx < 0 && (idx = sizes_find("")) < 0)
302 return;
303 snprintf(bracketsizes[idx][0], sizeof(bracketsizes[idx][0]), "%s", sign);
304 for (i = 1; i < NSIZES; i++)
305 snprintf(bracketsizes[idx][i], sizeof(bracketsizes[idx][i]),
306 "%s", sizes[i - 1] ? sizes[i - 1] : "");
309 /* global variables */
310 int e_axisheight = 23; /* axis height */
311 int e_minimumsize = 5; /* minimum size */
312 int e_overhang = 7;
313 int e_nulldelim = 12;
314 int e_scriptspace = 12;
315 int e_thinspace = 17;
316 int e_mediumspace = 22;
317 int e_thickspace = 28;
318 int e_num1 = 70; /* minimum numerator rise */
319 int e_num2 = 40;
320 int e_denom1 = 70; /* minimum denominator fall */
321 int e_denom2 = 36;
322 int e_sup1 = 42;
323 int e_sup2 = 37;
324 int e_sup3 = 28;
325 int e_sub1 = 20;
326 int e_sub2 = 23;
327 int e_supdrop = 38;
328 int e_subdrop = 5;
329 int e_xheight = 45;
330 int e_rulethickness = 4;
331 int e_bigopspacing1 = 11;
332 int e_bigopspacing2 = 17;
333 int e_bigopspacing3 = 20;
334 int e_bigopspacing4 = 60;
335 int e_bigopspacing5 = 10;
336 int e_columnsep = 100;
337 int e_baselinesep = 140;
338 int e_bodyheight = 70;
339 int e_bodydepth = 25;
341 static struct gvar {
342 char *name;
343 int *ref;
344 } gvars[] = {
345 {"axis_height", &e_axisheight},
346 {"minimum_size", &e_minimumsize},
347 {"over_hang", &e_overhang},
348 {"null_delimiter_space", &e_nulldelim},
349 {"script_space", &e_scriptspace},
350 {"thin_space", &e_thinspace},
351 {"medium_space", &e_mediumspace},
352 {"thick_space", &e_thickspace},
353 {"num1", &e_num1},
354 {"num2", &e_num2},
355 {"denom1", &e_denom1},
356 {"denom2", &e_denom2},
357 {"sup1", &e_sup1},
358 {"sup2", &e_sup2},
359 {"sup3", &e_sup3},
360 {"sub1", &e_sub1},
361 {"sub2", &e_sub2},
362 {"sup_drop", &e_supdrop},
363 {"sub_drop", &e_subdrop},
364 {"x_height", &e_xheight},
365 {"default_rule_thickness", &e_rulethickness},
366 {"big_op_spacing1", &e_bigopspacing1},
367 {"big_op_spacing2", &e_bigopspacing2},
368 {"big_op_spacing3", &e_bigopspacing3},
369 {"big_op_spacing4", &e_bigopspacing4},
370 {"big_op_spacing5", &e_bigopspacing5},
371 {"column_sep", &e_columnsep},
372 {"baseline_sep", &e_baselinesep},
373 {"body_height", &e_bodyheight},
374 {"body_depth", &e_bodydepth},
377 void def_set(char *name, int val)
379 int i;
380 for (i = 0; i < LEN(gvars); i++)
381 if (!strcmp(gvars[i].name, name))
382 *gvars[i].ref = val;
385 /* superscript style */
386 int ts_sup(int style)
388 int sz = MIN(2, TS_SZ(style) + 1);
389 return TS_MK(sz, TS_0(style));
392 /* subscript style */
393 int ts_sub(int style)
395 int sz = MIN(2, TS_SZ(style) + 1);
396 return TS_MK(sz, 1);
399 /* numerator style */
400 int ts_num(int style)
402 int sz;
403 if (TS_DX(style))
404 return TS_0(style) ? TS_T0 : TS_T;
405 sz = MIN(2, TS_SZ(style) + 1);
406 return TS_MK(sz, TS_0(style));
409 /* denominator style */
410 int ts_denom(int style)
412 int sz;
413 if (TS_DX(style))
414 return TS_T0;
415 sz = MIN(2, TS_SZ(style) + 1);
416 return TS_MK(sz, 1);
419 /* extra line-break cost */
420 static int brcost_type[32];
421 static int brcost_cost[32];
422 static int brcost_n;
424 int def_brcost(int type)
426 int i;
427 for (i = 0; i < brcost_n; i++)
428 if (brcost_type[i] == type && brcost_cost[i] > 0)
429 return brcost_cost[i];
430 return 100000;
433 void def_brcostput(int type, int cost)
435 int i;
436 if (type == 0)
437 brcost_n = 0;
438 for (i = 0; i < brcost_n; i++)
439 if (brcost_type[i] == type)
440 break;
441 if (type <= 0 || i + (i >= brcost_n) >= LEN(brcost_type))
442 return;
443 brcost_type[i] = type;
444 brcost_cost[i] = cost;
445 if (i >= brcost_n)
446 brcost_n = i + 1;
449 /* at which characters equations are chopped */
450 static char chopped[256] = "^~\"\t";
452 int def_chopped(int c)
454 return strchr("\n {}", c) != NULL || strchr(chopped, c) != NULL;
457 void def_choppedset(char *c)
459 strcpy(chopped, c);