1 /* MathType equation to LaTeX converter
2 *
3 * Ported 2000.04.03 by Steve Swanson, steve@mackichan.com
4 * Initial implementation by Jack Medd. Originally part of
5 * RTF to LaTeX converter in Scientific WorkPlace (http://www.mackichan.com).
6 *
7 * The MathType equation format were described at
8 * http://www.mathtype.com/support/tech/MTEF4.htm
9 * http://www.mathtype.com/support/tech/MTEF5.htm
10 * http://www.mathtype.com/support/tech/MTEF_storage.htm
11 * http://www.mathtype.com/support/tech/encodings/mtcode.stm
12 * Various undocumented details determined by debugging and intuition.
13 *
14 * Access to these pages is available at
15 * http://web.archive.org/web/20010304110708/http://mathtype.com/support/tech/MTEF5.htm
16 * http://web.archive.org/web/20010304110708/http://mathtype.com/support/tech/MTEF4.htm
17 * http://web.archive.org/web/20010304110708/http://mathtype.com/support/tech/MTEF3.htm
18 * http://web.archive.org/web/20010304111449/http://mathtype.com/support/tech/MTEF_storage.htm
19 * http://web.archive.org/web/20021020115826/http://www.mathtype.com/support/tech/encodings/mtcode.stm
20 */
21
22 # include <stdint.h>
23 # include <stdio.h>
24 # include <string.h>
25 # include <stdlib.h>
26 # include <ctype.h>
27
28 # include "rtf.h"
29 # include "rtf2latex2e.h"
30 # include "eqn.h"
31 # include "eqn_support.h"
32
33 # define DEBUG_PARSING 0
34 # define DEBUG_TRANSLATION 0
35 # define DEBUG_TEMPLATE 0
36 # define DEBUG_FONT 0
37 # define DEBUG_EMBELLS 0
38 # define DEBUG_CHAR 0
39 # define DEBUG_MODE 0
40 # define DEBUG_SIZE 0
41 # define DEBUG_JOIN 0
42 # define DEBUG_LINE 0
43 # define DEBUG_FUNCTION 0
44 # define DEBUG_EQUATION (DEBUG_PARSING || DEBUG_TRANSLATION || DEBUG_TEMPLATE)
45
46
47 static MT_OBJLIST *Eqn_GetObjectList(MTEquation * eqn, unsigned char *src, int *src_index, int num_objs);
48 static char *Eqn_TranslateObjects(MTEquation * eqn, MT_OBJLIST * the_list);
49 extern void hexdump (void *ptr, void *zero, uint32_t length, char *msg);
50
51 # define EQN_MODE_TEXT 0
52 # define EQN_MODE_INLINE 1
53 # define EQN_MODE_DISPLAY 2
54 # define EQN_MODE_EQNARRAY 3
55
56 /* Various local data which used to be in rtf2latex.ini. Initialized at bottom of file. */
57 extern char *Profile_FUNCTIONS[];
58 extern char *Profile_VARIABLES[];
59 extern char *Profile_PILEtranslation[];
60 extern char *Profile_MT_CHARSET_ATTS[];
61 extern char *Profile_CHARTABLE[];
62 extern char *Profile_TEMPLATES[];
63 extern char *Profile_TEMPLATES_5[];
64 extern char *Template_EMBELLS[];
65
66 char * typeFaceName[NUM_TYPEFACE_SLOTS] =
67 {
68 "ZERO",
69 "TEXT",
70 "FUNCTION",
71 "VARIABLE",
72 "LCGREEK",
73 "UCGREEK",
74 "SYMBOL",
75 "VECTOR",
76 "NUMBER",
77 "USER1",
78 "USER2",
79 "MTEXTRA",
80 "UNKNOWN",
81 "UNKNOWN",
82 "UNKNOWN",
83 "UNKNOWN",
84 "UNKNOWN",
85 "UNKNOWN",
86 "UNKNOWN",
87 "UNKNOWN",
88 "UNKNOWN",
89 "TEXT_FE",
90 "EXPAND",
91 "MARKER",
92 "SPACE",
93 "UNKNOWN",
94 "UNKNOWN",
95 "UNKNOWN",
96 "UNKNOWN",
97 "UNKNOWN",
98 "UNKNOWN",
99 "UNKNOWN"
100 };
101
102 static
ToBuffer(char * src,char * buffer,uint32_t * off,uint32_t * lim)103 char *ToBuffer(char *src, char *buffer, uint32_t *off, uint32_t *lim)
104 {
105
106 uint32_t zln = (uint32_t) strlen(src) + 1;
107
108 if (*off + zln + 256 >= *lim) {
109 char *newbuf;
110 *lim = *off + zln + 1024;
111 newbuf = (char *) malloc(*lim);
112 strcpy(newbuf, buffer);
113 free(buffer);
114 buffer = newbuf;
115 }
116
117 strcpy(buffer + *off, src);
118 *off += zln - 1;
119 free(src);
120
121 return buffer;
122 }
123
SetComment(EQ_STRREC * strs,int lev,char * src)124 static void SetComment(EQ_STRREC * strs, int lev, char *src)
125 {
126 strs[0].log_level = lev;
127 strs[0].do_delete = 1;
128 strs[0].ilk = Z_COMMENT;
129 strs[0].is_line = 0;
130
131 if (src) {
132 uint32_t zln = (uint32_t) strlen(src) + 1;
133 char *newbuf = (char *) malloc( (size_t) zln);
134 strcpy(newbuf, src);
135 strs[0].data = newbuf;
136 } else
137 strs[0].data = (char *) NULL;
138 }
139
print_tag(uint8_t tag,int src_index)140 static void print_tag(uint8_t tag, int src_index)
141 {
142 switch (tag) {
143 case 0:
144 RTFMsg("[%03d] %-14s\n", src_index, "END");
145 break;
146 case 1:
147 RTFMsg("[%03d] %-14s\n", src_index, "LINE");
148 break;
149 case 2:
150 RTFMsg("[%03d] %-14s\n", src_index, "CHAR");
151 break;
152 case 3:
153 RTFMsg("[%03d] %-14s\n", src_index, "TMPL");
154 break;
155 case 4:
156 RTFMsg("[%03d] %-14s\n", src_index, "PILE");
157 break;
158 case 5:
159 RTFMsg("[%03d] %-14s\n", src_index, "MATRIX");
160 break;
161 case 6:
162 RTFMsg("[%03d] %-14s\n", src_index, "EMBELL");
163 break;
164 case 7:
165 RTFMsg("[%03d] %-14s\n", src_index, "RULER");
166 break;
167 case 8:
168 RTFMsg("[%03d] %-14s\n", src_index, "FONT_STYLE_DEF");
169 break;
170 case 9:
171 RTFMsg("[%03d] %-14s\n", src_index, "SIZE");
172 break;
173 case 10:
174 RTFMsg("[%03d] %-14s\n", src_index, "FULL");
175 break;
176 case 11:
177 RTFMsg("[%03d] %-14s\n", src_index, "SUB");
178 break;
179 case 12:
180 RTFMsg("[%03d] %-14s\n", src_index, "SUB2");
181 break;
182 case 13:
183 RTFMsg("[%03d] %-14s\n", src_index, "SYM");
184 break;
185 case 14:
186 RTFMsg("[%03d] %-14s\n", src_index, "SUBSYM");
187 break;
188 case 15:
189 RTFMsg("[%03d] %-14s\n", src_index, "COLOR");
190 break;
191 case 16:
192 RTFMsg("[%03d] %-14s\n", src_index, "COLOR_DEF");
193 break;
194 case 17:
195 RTFMsg("[%03d] %-14s\n", src_index, "FONT_DEF");
196 break;
197 case 18:
198 RTFMsg("[%03d] %-14s\n", src_index, "EQN_PREFS");
199 break;
200 case 19:
201 RTFMsg("[%03d] %-14s\n", src_index, "ENCODING_DEF");
202 break;
203 default:
204 RTFMsg("[%03d] %-14s\n", src_index, "FUTURE");
205 break;
206 }
207 }
208
209 /*
210 * Nibble routines
211 */
HiNibble(unsigned char x)212 static unsigned char HiNibble(unsigned char x)
213 {
214 // fprintf(stderr, "x=%d, high=%d, shifted=%d\n",x,(x & 0xF0),(x & 0xF0)/16);
215 return (unsigned char) ((x & 0xF0)/16);
216 }
217
LoNibble(unsigned char x)218 static unsigned char LoNibble(unsigned char x)
219 {
220 return (x & 0x0F);
221 }
222
PrintNibble(unsigned char n)223 static void PrintNibble(unsigned char n)
224 {
225 if (1)
226 return;
227
228 if (n <= 9)
229 fprintf(stderr, "%d", n);
230 else if (n == 0x0A)
231 fprintf(stderr, ".");
232 else if (n == 0x0B)
233 fprintf(stderr, "-");
234 else if (n == 0x0F)
235 fprintf(stderr, " ");
236 else
237 RTFPanic("Bad nibble\n");
238 }
239
PrintNibbleDimension(unsigned char n)240 static void PrintNibbleDimension(unsigned char n)
241 {
242 if (1)
243 return;
244 switch (n) {
245 case 0:
246 fprintf(stderr, "in ");
247 break;
248 case 1:
249 fprintf(stderr, "cm ");
250 break;
251 case 2:
252 fprintf(stderr, "pt ");
253 break;
254 case 3:
255 fprintf(stderr, "pc ");
256 break;
257 case 4:
258 fprintf(stderr, " %% ");
259 break;
260 default:
261 RTFPanic("Bad nibble\n");
262 }
263 }
264
265
SkipNibbles(unsigned char * p,int num)266 static int SkipNibbles(unsigned char *p, int num)
267 {
268 unsigned char hi, lo;
269 int nbytes = 0;
270 int count = 1;
271 int new_str = 1;
272
273 if (0) fprintf(stderr, " #%02d -- ", count);
274 while (count <= num) {
275
276 hi = HiNibble(*(p + nbytes));
277 lo = LoNibble(*(p + nbytes));
278 nbytes++;
279
280 if (new_str)
281 PrintNibbleDimension(hi);
282 else
283 PrintNibble(hi);
284
285 new_str = 0;
286 if (hi == 0x0F) {
287 new_str = 1;
288 count++;
289 if (0) fprintf(stderr, " ---> total of %d bytes\n #%02d -- ", nbytes, count);
290 }
291
292 if (new_str)
293 PrintNibbleDimension(lo);
294 else
295 PrintNibble(lo);
296
297 new_str = 0;
298 if (lo == 0x0F) {
299 new_str = 1;
300 count++;
301 if (0) fprintf(stderr, " ---> total of %d bytes\n #%02d -- ", nbytes, count);
302 }
303 }
304 if (0) fprintf(stderr, "\n");
305
306 return nbytes;
307 }
308
309
310 /* section contains strings of the form */
311 /* key=data */
312 static
GetProfileStr(char ** section,char * key,char * data,int datalen)313 uint32_t GetProfileStr(char **section, char *key, char *data, int datalen)
314 {
315 char **rover;
316 size_t keylen;
317
318 data[0] = '\0';
319 if (key == NULL) return 0;
320 keylen = strlen(key);
321
322 for (rover = §ion[0]; *rover; ++rover) {
323 if (strncmp(*rover, key, keylen) == 0) {
324 strncpy(data, *rover + keylen + 1, (size_t) (datalen - 1)); /* skip over = (no check for white space */
325 data[datalen - 1] = '\0'; /* null terminate */
326 return ((uint32_t) strlen(data));
327 }
328 }
329
330 return 0;
331 }
332
333
334 /* this mangles the contents of strs[].data, so just call once! */
335 static
Eqn_JoinStrings(MTEquation * eqn,EQ_STRREC * strs,int num_strs)336 char *Eqn_JoinStrings(MTEquation * eqn, EQ_STRREC * strs, int num_strs)
337 {
338 char join[8192], buf[128];
339 char *p, *substition_text, *marker, *thetex;
340 char *vars[3];
341 int i, j, id, is_pile;
342
343 if (DEBUG_JOIN) {
344 for (i=0; i<num_strs; i++)
345 fprintf(stderr," is_line=%d, strs[%d].data=%s\n", strs[i].is_line, i, strs[i].data);
346 }
347
348 *join = '\0';
349
350 for (i=0; i<num_strs; i++) {
351
352 if (!strs[i].data) continue;
353
354 if (strs[i].log_level > eqn->log_level) continue;
355
356 if (strs[i].ilk != Z_TMPL) {
357 strcat(join, strs[i].data);
358 continue;
359 }
360
361 /* the current string is a TMPL and needs to be filled and added */
362 /* e.g., dat = "\sqrt[#2]{#1}" */
363
364 p = strs[i].data;
365
366 while (*p) {
367
368 marker = strchr(p, '#');
369 if (!marker) {
370 strcat(join, p);
371 break;
372 }
373
374 *marker = '\0';
375 strcat(join, p);
376 p = marker + 1;
377
378 /* #1[L][STARTSUB][ENDSUB] ... substitute text according to byzantine scheme */
379
380 /* only #1, #2, and #3 are used */
381 id = *p - '1';
382 if (id < 0 || id > 3) break;
383 p++;
384
385 /* Extract the bracketed items */
386 /* vars[0]="L", vars[1]="STARTSUB", vars[2]="ENDSUB" */
387 /* only vars[1] and vars[2] are used */
388
389 vars[1] = NULL;
390 vars[2] = NULL;
391 j = 0;
392 while (*p == '[') {
393 p++;
394 marker = strchr(p, ']');
395 if (!marker) break;
396 *marker = '\0';
397 vars[j++] = p;
398 p = marker+1;
399 }
400
401 /* This is pretty confusing. All the strs[] have an is_line flag */
402 /* only strs[] entries that have this flag set may be used for replacement */
403 /* The replacement text for #1 or #2 or #3 is the first, second, or third */
404 /* strs[] entry that has its flag set. */
405
406 thetex = NULL;
407 for (j=i+1; j<num_strs; j++) {
408 if (strs[j].is_line == 0) continue;
409
410 if (id == 0) {
411 thetex = strs[j].data;
412 strs[j].log_level = 100; /* mark this entry as used */
413 is_pile = (strs[j].is_line == 2) ? 1 : 0;
414 break;
415 }
416 id--; /* one string closer to our goal */
417 }
418
419 /* this should not happen, but if it does, just go on to the next character */
420 if (!thetex) continue;
421
422 if (GetProfileStr(Profile_VARIABLES, vars[1], buf, 128)) {
423
424 substition_text = buf;
425 marker = strchr(buf, ',');
426
427 if (is_pile)
428 substition_text = marker + 1;
429 else
430 *marker = '\0';
431
432 strcat(join, substition_text);
433 }
434
435 strcat(join, thetex);
436
437 if (GetProfileStr(Profile_VARIABLES, vars[2], buf, 128)) {
438
439 substition_text = buf;
440 marker = strchr(buf, ',');
441
442 if (is_pile)
443 substition_text = marker + 1;
444 else
445 *marker = 0;
446
447 strcat(join, substition_text);
448 }
449 }
450 }
451
452 for (i=0; i<num_strs; i++)
453 if (strs[i].do_delete && strs[i].data) {
454 free(strs[i].data);
455 strs[i].data = NULL;
456 }
457
458 thetex = (char *) malloc(strlen(join)+1);
459 strcpy(thetex, join);
460 if (DEBUG_JOIN) fprintf(stderr,"final join='%s'\n", thetex);
461 return thetex;
462 }
463
464 /* delete routines */
465
466
467
468 static
DeleteTabstops(MT_TABSTOP * the_list)469 void DeleteTabstops(MT_TABSTOP * the_list)
470 {
471 MT_TABSTOP *del_node;
472
473 while (the_list) {
474 del_node = the_list;
475 the_list = (MT_TABSTOP *) (the_list->next);
476 free(del_node);
477 }
478 }
479
480
481 static
DeleteEmbells(MT_EMBELL * the_list)482 void DeleteEmbells(MT_EMBELL * the_list)
483 {
484 MT_EMBELL *del_node;
485 while (the_list) {
486 del_node = the_list;
487 the_list = (MT_EMBELL *) the_list->next;
488 free(del_node);
489 }
490 }
491
492
493 static
DeleteObjectList(MT_OBJLIST * the_list)494 void DeleteObjectList(MT_OBJLIST * the_list)
495 {
496 MT_OBJLIST *del_node;
497 MT_LINE *line;
498 MT_CHAR *charptr;
499
500 while (the_list) {
501
502 del_node = the_list;
503 the_list = (void *) the_list->next;
504
505 switch (del_node->tag) {
506
507 case LINE:{
508 line = (MT_LINE *) del_node->obj_ptr;
509 if (line) {
510 if (line->ruler) {
511 DeleteTabstops(line->ruler->tabstop_list);
512 free(line->ruler);
513 }
514
515 if (line->object_list)
516 DeleteObjectList(line->object_list);
517 free(line);
518 }
519 }
520 break;
521
522 case CHAR:{
523 charptr = (MT_CHAR *) del_node->obj_ptr;
524 if (charptr) {
525 if (charptr->embellishment_list)
526 DeleteEmbells(charptr->embellishment_list);
527 free(charptr);
528 }
529 }
530 break;
531
532 case TMPL:{
533 MT_TMPL *tmpl = (MT_TMPL *) del_node->obj_ptr;
534 if (tmpl) {
535 if (tmpl->subobject_list)
536 DeleteObjectList(tmpl->subobject_list);
537 free(tmpl);
538 }
539 }
540 break;
541
542 case PILE:{
543 MT_PILE *pile = (MT_PILE *) del_node->obj_ptr;
544 if (pile) {
545 if (pile->line_list)
546 DeleteObjectList(pile->line_list);
547 free(pile);
548 }
549 }
550 break;
551
552 case MATRIX:{
553 MT_MATRIX *matrix = (MT_MATRIX *) del_node->obj_ptr;
554 if (matrix) {
555 if (matrix->element_list)
556 DeleteObjectList(matrix->element_list);
557 free(matrix);
558 }
559 }
560 break;
561
562 case EMBELL:
563 break;
564
565 case RULER:{
566 MT_RULER *ruler = (MT_RULER *) del_node->obj_ptr;
567 if (ruler) {
568 if (ruler->tabstop_list)
569 DeleteTabstops(ruler->tabstop_list);
570 free(ruler);
571 }
572 }
573 break;
574
575 case FONT:{
576 MT_FONT *font = (MT_FONT *) del_node->obj_ptr;
577 if (font) {
578 if (font->zname)
579 free(font->zname);
580 free(font);
581 }
582 }
583 break;
584
585 case SIZE:
586 case FULL:
587 case SUB:
588 case SUB2:
589 case SYM:
590 case SUBSYM:{
591 MT_SIZE *size = (MT_SIZE *) del_node->obj_ptr;
592 if (size) {
593 free(size);
594 }
595 }
596 break;
597
598 default:
599 break;
600 }
601
602 free(del_node);
603 } /* while ( the_list ) */
604 }
605
Eqn_Destroy(MTEquation * eqn)606 void Eqn_Destroy(MTEquation * eqn)
607 {
608 if (eqn->o_list) {
609 DeleteObjectList(eqn->o_list);
610 eqn->o_list = NULL;
611 }
612 if (eqn->atts_table) {
613 free(eqn->atts_table);
614 eqn->atts_table = NULL;
615 }
616 if (eqn->m_latex_start) {
617 free(eqn->m_latex_start);
618 eqn->m_latex_start = NULL;
619 }
620 if (eqn->m_latex_end) {
621 free(eqn->m_latex_end);
622 eqn->m_latex_end = NULL;
623 }
624 if (eqn->m_latex) {
625 free(eqn->m_latex);
626 eqn->m_latex = NULL;
627 }
628
629 }
630
setMathMode(MTEquation * eqn,int mode)631 static void setMathMode(MTEquation * eqn, int mode)
632 {
633 char s[50];
634 if (DEBUG_MODE || g_input_file_type==TYPE_EQN) fprintf(stderr,"old=%d, new=%d\n",eqn->m_mode,mode);
635
636 switch (mode) {
637 case EQN_MODE_TEXT:
638 switch (eqn->m_mode) {
639 case EQN_MODE_TEXT:
640 break;
641 case EQN_MODE_INLINE:
642 strcpy(s," $");
643 if (eqn->m_latex_end) free(eqn->m_latex_end);
644 eqn->m_latex_end = strdup(s);
645 break;
646 case EQN_MODE_DISPLAY:
647 strcpy(s," $$\n");
648 if (eqn->m_latex_end) free(eqn->m_latex_end);
649 eqn->m_latex_end = strdup(s);
650 break;
651 case EQN_MODE_EQNARRAY:
652 strcpy(s,"\\end{eqnarray}\n");
653 if (eqn->m_latex_end) free(eqn->m_latex_end);
654 eqn->m_latex_end = strdup(s);
655 break;
656 }
657 break;
658
659 case EQN_MODE_INLINE:
660 switch (eqn->m_mode) {
661 case EQN_MODE_TEXT:
662 if (eqn->m_latex_start) free(eqn->m_latex_start);
663 eqn->m_latex_start = strdup("$");
664 break;
665 case EQN_MODE_INLINE:
666 break;
667 case EQN_MODE_DISPLAY:
668 fprintf(stderr,"Bizarre case of switching from display to inline??\n");
669 break;
670 case EQN_MODE_EQNARRAY:
671 fprintf(stderr,"Bizarre case of switching from eqnarray to inline??\n");
672 break;
673 }
674 break;
675
676 case EQN_MODE_DISPLAY:
677 switch (eqn->m_mode) {
678 case EQN_MODE_TEXT:
679 if (eqn->m_latex_start) free(eqn->m_latex_start);
680 eqn->m_latex_start = strdup("$$");
681 break;
682 case EQN_MODE_INLINE:
683 fprintf(stderr,"Bizarre case of switching from inline to display??\n");
684 break;
685 case EQN_MODE_DISPLAY:
686 break;
687 case EQN_MODE_EQNARRAY:
688 fprintf(stderr,"Bizarre case of switching from eqnarry to display??\n");
689 break;
690 }
691 break;
692
693 case EQN_MODE_EQNARRAY:
694 switch (eqn->m_mode) {
695 case EQN_MODE_TEXT:
696 if (eqn->m_latex_start) free(eqn->m_latex_start);
697 eqn->m_latex_start = strdup("\\begin{eqnarray}");
698 break;
699 case EQN_MODE_INLINE:
700 fprintf(stderr,"Bizarre case of switching from inline to eqnarry??\n");
701 break;
702 case EQN_MODE_DISPLAY:
703 fprintf(stderr,"Bizarre case of switching from display to eqnarry??\n");
704 break;
705 case EQN_MODE_EQNARRAY:
706 break;
707 }
708 break;
709 }
710
711 eqn->m_mode = mode;
712
713 /* if (strlen(s))
714 return strdup(s);
715 else
716 return NULL;*/
717 }
718
GetAttribute(MTEquation * eqn,unsigned char * src,uint8_t * attrs)719 static int GetAttribute(MTEquation * eqn, unsigned char *src, uint8_t *attrs)
720 {
721 if (eqn->m_mtef_ver < 5) {
722 *attrs = HiNibble(*src);
723 return 1;
724 }
725
726 *attrs = *(src + 1);
727 return 2;
728 }
729
730 static
GetNudge(unsigned char * src,int16_t * x,int16_t * y)731 int GetNudge(unsigned char *src, int16_t *x, int16_t *y)
732 {
733
734 int nudge_length;
735 int16_t tmp;
736
737 unsigned char b1 = *src;
738 unsigned char b2 = *(src + 1);
739
740
741 if (b1 == 128 && b2 == 128) {
742 tmp = (int16_t) *(src + 2);
743 tmp |= (int16_t) *(src + 3) << 8;
744 *x = tmp;
745 tmp = (int16_t) *(src + 4);
746 tmp |= (int16_t) *(src + 5) << 8;
747 *y = tmp;
748 nudge_length = 6;
749 } else {
750 *x = b1;
751 *y = b2;
752 nudge_length = 2;
753 }
754
755 if (g_input_file_type==TYPE_EQN) fprintf(stderr, "nudge gotten size=%d",nudge_length);
756
757 return nudge_length;
758 }
759
Eqn_inputRULER(MTEquation * eqn,unsigned char * src,int * src_index)760 static MT_RULER *Eqn_inputRULER(MTEquation * eqn, unsigned char *src, int *src_index)
761 {
762 MT_RULER *new_ruler;
763 MT_TABSTOP *head, *curr, *new_stop;
764 uint8_t i, num_stops, tag;
765
766 /* if we arrived here from LINE, then there does not seem to be
767 a proper RULER tag. Skip the tag only if it is a RULER */
768 tag = *(src + *src_index) & 0x0F;
769 if (tag == 7)
770 (*src_index)++; /* step over ruler tag */
771
772 head = NULL;
773 num_stops = *(src + *src_index);
774 (*src_index)++;
775
776 for (i=0; i < num_stops; i++) {
777 new_stop = (MT_TABSTOP *) malloc(sizeof(MT_TABSTOP));
778 new_stop->next = NULL;
779 new_stop->type = *(src + *src_index);
780 (*src_index)++;
781
782 new_stop->offset = *(src + *src_index);
783 (*src_index)++;
784 new_stop->offset |= *(src + *src_index) << 8;
785 (*src_index)++;
786
787 if (head)
788 curr->next = (struct MT_TABSTOP *) new_stop;
789 else
790 head = new_stop;
791 curr = new_stop;
792 }
793
794 new_ruler = (MT_RULER *) malloc(sizeof(MT_RULER));
795 new_ruler->n_stops = num_stops;
796 new_ruler->tabstop_list = head;
797
798 return new_ruler;
799 }
800
801
802 /*
803 * record type (1)
804 * options
805 * [nudge] if mtefOPT_NUDGE is set
806 * [line spacing] if mtefOPT_LINE_LSPACE is set (16-bit integer)
807 * [RULER record] if mtefOPT_LP_RULER is set
808 * object list contents of line (a single pile, characters and templates, or nothing)
809 */
810
Eqn_inputLINE(MTEquation * eqn,unsigned char * src,int * src_index)811 static MT_LINE *Eqn_inputLINE(MTEquation * eqn, unsigned char *src,
812 int *src_index)
813 {
814 unsigned char attrs;
815 MT_LINE *new_line = (MT_LINE *) malloc(sizeof(MT_LINE));
816 new_line->nudge_x = 0;
817 new_line->nudge_y = 0;
818 new_line->line_spacing = 0;
819 new_line->ruler = NULL;
820 new_line->object_list = NULL;
821
822 *src_index += GetAttribute(eqn, src+*src_index, &attrs);
823
824 if (DEBUG_LINE) fprintf(stderr, "LINE options = 0x%02x\n", attrs);
825
826 if (attrs & xfLMOVE)
827 *src_index += GetNudge(src + *src_index, &new_line->nudge_x, &new_line->nudge_y);
828
829 if (attrs & xfLSPACE) {
830 new_line->line_spacing = *(src + *src_index);
831 (*src_index)++;
832 }
833
834 if (attrs & xfRULER)
835 new_line->ruler = Eqn_inputRULER(eqn, src, src_index);
836
837 if (!(attrs & xfNULL))
838 new_line->object_list = Eqn_GetObjectList(eqn, src, src_index, 0);
839
840 return new_line;
841 }
842
843
Eqn_inputEMBELL(MTEquation * eqn,unsigned char * src,int * src_index)844 static MT_EMBELL *Eqn_inputEMBELL(MTEquation * eqn, unsigned char *src, int *src_index)
845 {
846 unsigned char attrs, tag;
847 MT_EMBELL *head = NULL;
848 MT_EMBELL *new_embell = NULL;
849 MT_EMBELL *curr = NULL;
850 tag = EMBELL;
851
852 while (tag == EMBELL) {
853 new_embell = (MT_EMBELL *) malloc(sizeof(MT_EMBELL));
854 new_embell->next = NULL;
855 new_embell->nudge_x = 0;
856 new_embell->nudge_y = 0;
857
858 *src_index += GetAttribute(eqn, src+*src_index, &attrs);
859
860 if (attrs & xfLMOVE)
861 *src_index += GetNudge(src + *src_index, &new_embell->nudge_x, &new_embell->nudge_y);
862
863 new_embell->embell = *(src + *src_index);
864 if (DEBUG_EMBELLS || g_input_file_type==TYPE_EQN)
865 fprintf(stderr, "[%-3d] EMBELL --- embell=%d\n", *src_index, (int) new_embell->embell);
866 (*src_index)++;
867
868 if (head)
869 curr->next = (struct MT_EMBELL *) new_embell;
870 else
871 head = new_embell;
872 curr = new_embell;
873
874 if (eqn->m_mtef_ver == 5)
875 tag = *(src + *src_index);
876 else
877 tag = LoNibble(*(src + *src_index));
878 }
879
880 (*src_index)++; /* advance over end byte */
881
882 return head;
883 }
884
885
886 /*
887 * attributes
888 * [nudge] if xfLMOVE is set
889 * [typeface] typeface value (see FONT below) + 128
890 * [character] 16-bit character value (encoding depends on typeface)
891 * [embellishment list] if xfEMBELL is set (embellishments)
892 */
893
Eqn_inputCHAR(MTEquation * eqn,unsigned char * src,int * src_index)894 static MT_CHAR *Eqn_inputCHAR(MTEquation * eqn, unsigned char *src, int *src_index)
895 {
896 unsigned char attrs;
897 MT_CHAR *new_char = (MT_CHAR *) malloc(sizeof(MT_CHAR));
898 new_char->nudge_x = 0;
899 new_char->nudge_y = 0;
900 new_char->mtchar = 0;
901 new_char->bits16 = 0;
902 new_char->embellishment_list = (MT_EMBELL *) NULL;
903
904 *src_index += GetAttribute(eqn, src+*src_index, &attrs);
905 new_char->atts = attrs;
906
907 if (new_char->atts & CHAR_NUDGE)
908 *src_index += GetNudge(src + *src_index, &new_char->nudge_x, &new_char->nudge_y);
909
910 new_char->typeface = *(src + *src_index);
911 (*src_index)++;
912
913 if (eqn->m_mtef_ver < 5) {
914 new_char->character = *(src + *src_index);
915 (*src_index)++;
916 if (eqn->m_platform == PLATFORM_WIN) {
917 new_char->character |= *(src + *src_index) << 8;
918 (*src_index)++;
919 }
920
921 } else {
922
923 /* nearly always have a 16 bit MT character */
924 if (!(new_char->atts & CHAR_ENC_NO_MTCODE)) {
925 new_char->character = *(src + *src_index);
926 (*src_index)++;
927 new_char->character |= *(src + *src_index) << 8;
928 (*src_index)++;
929 }
930
931 /* 02 05 84 bc 03 6d 06 00 11 00 02 04 86 */
932 if (new_char->atts & CHAR_ENC_CHAR_8) {
933 new_char->character = *(src + *src_index);
934 (*src_index)++;
935 }
936
937 if (new_char->atts & CHAR_ENC_CHAR_16) {
938 new_char->bits16 = *(src + *src_index);
939 (*src_index)++;
940 new_char->bits16 |= *(src + *src_index) << 8;
941 (*src_index)++;
942 }
943 }
944
945 if (g_input_file_type==TYPE_EQN || DEBUG_CHAR) {
946 fprintf(stderr, " '%c' or 0x%04x,", (int)new_char->character, (unsigned int) new_char->character);
947 fprintf(stderr, " typeface = %d mtchar=%u, 16bit=%u ",
948 (int) new_char->typeface-128, (unsigned int) new_char->mtchar, (unsigned int) new_char->bits16);
949 fprintf(stderr, " attr = 0x%02x \n", (unsigned int) new_char->atts);
950 }
951
952 if (eqn->m_mtef_ver == 5) {
953 if (new_char->atts & CHAR_EMBELL)
954 new_char->embellishment_list = Eqn_inputEMBELL(eqn, src, src_index);
955 } else {
956 if (new_char->atts & xfEMBELL)
957 new_char->embellishment_list = Eqn_inputEMBELL(eqn, src, src_index);
958 }
959
960
961 return new_char;
962 }
963
Eqn_inputTMPL(MTEquation * eqn,unsigned char * src,int * src_index)964 static MT_TMPL *Eqn_inputTMPL(MTEquation * eqn, unsigned char *src, int *src_index)
965 {
966 unsigned char attrs;
967 MT_TMPL *new_tmpl = (MT_TMPL *) malloc(sizeof(MT_TMPL));
968 new_tmpl->nudge_x = 0;
969 new_tmpl->nudge_y = 0;
970
971 *src_index += GetAttribute(eqn, src+*src_index, &attrs);
972
973 if (attrs & xfLMOVE)
974 *src_index += GetNudge(src + *src_index, &new_tmpl->nudge_x, &new_tmpl->nudge_y);
975
976 new_tmpl->selector = *(src + *src_index);
977 (*src_index)++;
978
979 new_tmpl->variation = *(src + *src_index);
980 (*src_index)++;
981
982 if (eqn->m_mtef_ver == 5 && (new_tmpl->variation & 0x80) ) {
983 new_tmpl->variation &= 0x7F;
984 new_tmpl->variation |= *(src + *src_index) << 8;
985 (*src_index)++;
986 RTFMsg("Two byte variation!\n");
987 }
988
989 new_tmpl->options = *(src + *src_index);
990 (*src_index)++;
991
992 // if (eqn->m_mtef_ver == 3 && 18 <= new_tmpl->selector && new_tmpl->selector <= 20)
993 // new_tmpl->variation = new_tmpl->variation >> 8;
994
995 if ( (DEBUG_PARSING && DEBUG_TEMPLATE) || g_input_file_type==TYPE_EQN)
996 fprintf(stderr, "TMPL : read sel=%2d var=0x%04x (%d.%d)\n",
997 (int) new_tmpl->selector, (unsigned int) new_tmpl->variation, (int) new_tmpl->selector, (int) new_tmpl->variation);
998
999 new_tmpl->subobject_list = Eqn_GetObjectList(eqn, src, src_index, 0);
1000
1001 return new_tmpl;
1002 }
1003
1004
Eqn_inputPILE(MTEquation * eqn,unsigned char * src,int * src_index)1005 static MT_PILE *Eqn_inputPILE(MTEquation * eqn, unsigned char *src,
1006 int *src_index)
1007 {
1008 unsigned char attrs;
1009 MT_PILE *new_pile = (MT_PILE *) malloc(sizeof(MT_PILE));
1010 new_pile->nudge_x = 0;
1011 new_pile->nudge_y = 0;
1012 new_pile->ruler = NULL;
1013
1014 *src_index += GetAttribute(eqn, src+*src_index, &attrs);
1015
1016 if (attrs & xfLMOVE)
1017 *src_index += GetNudge(src + *src_index, &new_pile->nudge_x, &new_pile->nudge_y);
1018
1019 new_pile->halign = *(src + *src_index);
1020 (*src_index)++;
1021
1022 new_pile->valign = *(src + *src_index);
1023 (*src_index)++;
1024
1025 if (attrs & xfRULER)
1026 new_pile->ruler = Eqn_inputRULER(eqn, src, src_index);
1027
1028 new_pile->line_list = Eqn_GetObjectList(eqn, src, src_index, 0);
1029
1030 return new_pile;
1031 }
1032
1033
Eqn_inputMATRIX(MTEquation * eqn,unsigned char * src,int * src_index)1034 static MT_MATRIX *Eqn_inputMATRIX(MTEquation * eqn, unsigned char *src,
1035 int *src_index)
1036 {
1037 uint8_t attrs, i, bytes;
1038
1039 MT_MATRIX *new_matrix = (MT_MATRIX *) malloc(sizeof(MT_MATRIX));
1040 new_matrix->nudge_x = 0;
1041 new_matrix->nudge_y = 0;
1042
1043 *src_index += GetAttribute(eqn, src+*src_index, &attrs);
1044
1045 if (attrs & xfLMOVE)
1046 *src_index += GetNudge(src + *src_index, &new_matrix->nudge_x, &new_matrix->nudge_y);
1047
1048 new_matrix->valign = *(src + *src_index);
1049 (*src_index)++;
1050 new_matrix->h_just = *(src + *src_index);
1051 (*src_index)++;
1052 new_matrix->v_just = *(src + *src_index);
1053 (*src_index)++;
1054 new_matrix->rows = *(src + *src_index);
1055 (*src_index)++;
1056 new_matrix->cols = *(src + *src_index);
1057 (*src_index)++;
1058
1059 /* row partition consists of (rows+1) two-bit values */
1060 bytes = (2 * (new_matrix->rows + 1) + 7) / 8;
1061 for (i=0; i<bytes; i++) {
1062 new_matrix->row_parts[i] = *(src + *src_index);
1063 (*src_index)++;
1064 }
1065
1066 /* col partition consists of (cols+1) two-bit values */
1067 bytes = (2 * (new_matrix->cols + 1) + 7) / 8;
1068 for (i=0; i<bytes; i++) {
1069 new_matrix->col_parts[i] = *(src + *src_index);
1070 (*src_index)++;
1071 }
1072
1073 new_matrix->element_list = Eqn_GetObjectList(eqn, src, src_index, 0);
1074
1075 return new_matrix;
1076 }
1077
Eqn_inputFONT(MTEquation * eqn,unsigned char * src,int * src_index)1078 static MT_FONT *Eqn_inputFONT(MTEquation * eqn, unsigned char *src,
1079 int *src_index)
1080 {
1081 uint32_t zln;
1082 MT_FONT *new_font = (MT_FONT *) malloc(sizeof(MT_FONT));
1083
1084 (*src_index)++; /* step over the tag */
1085
1086 new_font->tface = *(src + *src_index);
1087 (*src_index)++;
1088 new_font->style = *(src + *src_index);
1089 (*src_index)++;
1090
1091 zln = (uint32_t) strlen((char *) src + *src_index) + 1;
1092 new_font->zname = (char *) malloc(sizeof(char) * zln);
1093 strcpy((char *) new_font->zname, (char *) src + *src_index);
1094 *src_index += zln;
1095
1096 return new_font;
1097 }
1098
Eqn_inputSIZE(MTEquation * eqn,unsigned char * src,int * src_index)1099 static MT_SIZE *Eqn_inputSIZE(MTEquation * eqn, unsigned char *src,
1100 int *src_index)
1101 {
1102 unsigned char tag, option;
1103 MT_SIZE *new_size = (MT_SIZE *) malloc(sizeof(MT_SIZE));
1104 new_size->dsize = 0;
1105
1106 /* also works in MTEF5 because all supported tags are less than 16 */
1107 tag = *(src + *src_index) & 0x0F;
1108 (*src_index)++;
1109
1110 /* FULL or SUB or SUB2 or SYM or SUBSYM */
1111 if (tag >= FULL && tag <= SUBSYM) {
1112 // fprintf(stderr,"tag= %d\n",tag);
1113 new_size->type = tag;
1114 new_size->lsize = tag - FULL;
1115 return new_size;
1116 }
1117
1118 option = *(src + *src_index);
1119 (*src_index)++;
1120
1121 /* large dsize */
1122 if (option == 100) {
1123 new_size->type = option;
1124 new_size->lsize = *(src + *src_index);
1125 (*src_index)++;
1126 new_size->dsize = *(src + *src_index);
1127 (*src_index)++;
1128 new_size->dsize += (*(src + *src_index) << 8);
1129 (*src_index)++;
1130 return new_size;
1131 }
1132
1133 /* explicit point size */
1134 if (option == 101) {
1135 new_size->type = option;
1136 new_size->lsize = *(src + *src_index);
1137 (*src_index)++;
1138 new_size->lsize += (*(src + *src_index) << 8);
1139 (*src_index)++;
1140 return new_size;
1141 }
1142
1143 /* -128 < dsize < 128 */
1144 new_size->type = 0;
1145 new_size->lsize = option;
1146 new_size->dsize = *(src + *src_index) - 128;
1147 (*src_index)++;
1148 return new_size;
1149 }
1150
1151
1152 /*
1153 * Convert MT equation into internal form
1154 * at each Eqn_inputXXX call, the src_index is set to the XXX tag
1155 * so that the hi nibble can be used to obtain the options in
1156 * versions 1-4 of MTEF
1157 */
Eqn_GetObjectList(MTEquation * eqn,unsigned char * src,int * src_index,int num_objs)1158 static MT_OBJLIST *Eqn_GetObjectList(MTEquation * eqn, unsigned char *src, int *src_index, int num_objs)
1159 {
1160 static int subroutine_depth = 0;
1161 unsigned char c, size, curr_tag;
1162 int i,id;
1163 int tally = 0;
1164 MT_OBJLIST *head = (MT_OBJLIST *) NULL;
1165 MT_OBJLIST *curr;
1166 void *new_obj;
1167
1168 ++subroutine_depth;
1169 if (eqn->m_mtef_ver == 5)
1170 curr_tag = *(src + *src_index);
1171 else
1172 curr_tag = LoNibble(*(src + *src_index));
1173
1174 while (curr_tag != 0xFF) {
1175
1176 new_obj = (void *) NULL;
1177
1178 if (DEBUG_PARSING || g_input_file_type==TYPE_EQN) {
1179 print_tag(curr_tag, *src_index);
1180 hexdump(src+*src_index, src+*src_index, 16, NULL);
1181 }
1182
1183 switch (curr_tag) {
1184 case END:
1185 (*src_index)++;
1186 subroutine_depth--;
1187 return head;
1188 break;
1189
1190 case LINE:
1191 new_obj = (void *) Eqn_inputLINE(eqn, src, src_index);
1192 break;
1193 case CHAR:
1194 new_obj = (void *) Eqn_inputCHAR(eqn, src, src_index);
1195 break;
1196 case TMPL:
1197 new_obj = (void *) Eqn_inputTMPL(eqn, src, src_index);
1198 break;
1199 case PILE:
1200 new_obj = (void *) Eqn_inputPILE(eqn, src, src_index);
1201 break;
1202 case MATRIX:
1203 new_obj = (void *) Eqn_inputMATRIX(eqn, src, src_index);
1204 break;
1205
1206 case EMBELL:
1207 new_obj = (void *) Eqn_inputEMBELL(eqn, src, src_index);
1208 break;
1209
1210 case RULER:
1211 new_obj = (void *) Eqn_inputRULER(eqn, src, src_index);
1212 break;
1213 case FONT:
1214 new_obj = (void *) Eqn_inputFONT(eqn, src, src_index);
1215 break;
1216
1217 case SIZE:
1218 case FULL:
1219 case SUB:
1220 case SUB2:
1221 case SYM:
1222 case SUBSYM:
1223 new_obj = (void *) Eqn_inputSIZE(eqn, src, src_index);
1224 break;
1225
1226 case COLOR_DEF:
1227 break;
1228
1229 case FONT_DEF:
1230 (*src_index)++;
1231 id = *(src + *src_index);
1232 (*src_index)++;
1233 if (DEBUG_FONT) fprintf(stderr," ");
1234 while ((c = *(src + *src_index))) {
1235 if (DEBUG_FONT) fprintf(stderr,"%c",c);
1236 (*src_index)++;
1237 }
1238 if (DEBUG_FONT) fprintf(stderr," ==> %d\n",id);
1239 (*src_index)++;
1240 tally--;
1241 break;
1242
1243 case EQN_PREFS:
1244 (*src_index)++; /* skip tag */
1245 (*src_index)++; /* options */
1246
1247 size = *(src + *src_index); /* sizes[] */
1248 if (0) fprintf(stderr, " size array has %d entries\n", size);
1249 (*src_index)++;
1250 (*src_index) += SkipNibbles(src + *src_index, size);
1251
1252 size = *(src + *src_index); /* spaces[] */
1253 (*src_index)++;
1254 (*src_index) += SkipNibbles(src + *src_index, size);
1255
1256 size = *(src + *src_index); /* styles[] */
1257 (*src_index)++;
1258 if (0) fprintf(stderr, " style array has %d entries\n", size);
1259 for (i = 0; i < size; i++) {
1260 c = *(src + *src_index);
1261 (*src_index)++;
1262 if (c) {
1263 /* c = *(src + *src_index); */
1264 (*src_index)++;
1265 }
1266 }
1267 tally--;
1268 break;
1269
1270 case ENCODING_DEF:
1271 (*src_index)++; /* skip tag */
1272 while ((c = *(src + *src_index))) {
1273 if (0) fprintf(stderr, "%c", c);
1274 (*src_index)++;
1275 }
1276 if (0) fprintf(stderr, "\n");
1277 (*src_index)++; /* skip NULL */
1278 tally--;
1279 break;
1280
1281 default:
1282 (*src_index)++; /* skip tag */
1283 size = *(src + *src_index);
1284 (*src_index)++;
1285 size |= *(src + *src_index) << 8;
1286
1287 //Need to include a change to how the *src_index tag is incremented.
1288 //Although the MTEF v.5 documentation says otherwise, it appears the
1289 //index should be incremented by size-1, not size.
1290 (*src_index) += size;
1291
1292 fprintf(stderr, "Future tag = 0x%02x with size %d\n",curr_tag,size);
1293 fprintf(stderr,"--> ignoring!\n");
1294 tally--;
1295 break;
1296 }
1297
1298 if (new_obj) {
1299 MT_OBJLIST *new_node =
1300 (MT_OBJLIST *) malloc(sizeof(MT_OBJLIST));
1301 new_node->next = NULL;
1302 new_node->tag = curr_tag;
1303 new_node->obj_ptr = new_obj;
1304
1305 if (head)
1306 curr->next = (void *) new_node;
1307 else
1308 head = new_node;
1309 curr = new_node;
1310 }
1311
1312 if (eqn->m_mtef_ver == 5)
1313 curr_tag = *(src + *src_index);
1314 else
1315 curr_tag = LoNibble(*(src + *src_index));
1316
1317 tally++;
1318
1319 // fprintf(stderr,"depth=%d number of objects/total = %d/%d\n", subroutine_depth, tally, num_objs);
1320
1321 if (tally == num_objs) {
1322 subroutine_depth--;
1323 return head;
1324 }
1325
1326 } /* while loop thru MathType Objects */
1327
1328 (*src_index)++; /* step over end byte */
1329
1330 subroutine_depth--;
1331 return head;
1332 }
1333
1334 static
Eqn_LoadCharSetAtts(MTEquation * eqn,char ** table)1335 void Eqn_LoadCharSetAtts(MTEquation * eqn, char **table)
1336 {
1337 char key[16];
1338 char buff[16];
1339 uint8_t slot = 1;
1340 uint32_t zln;
1341
1342 eqn->atts_table = malloc(sizeof(MT_CHARSET_ATTS) * NUM_TYPEFACE_SLOTS);
1343
1344 while (slot <= NUM_TYPEFACE_SLOTS) {
1345 snprintf(key, 16, "%d", (int) slot + 128);
1346 zln = GetProfileStr(table, key, buff, 16);
1347 if (zln) {
1348 eqn->atts_table[slot - 1].mathattr = buff[0] - '0';
1349 eqn->atts_table[slot - 1].do_lookup = buff[2] - '0';
1350 eqn->atts_table[slot - 1].use_codepoint = buff[4] - '0';
1351 } else {
1352 eqn->atts_table[slot - 1].mathattr = 1;
1353 eqn->atts_table[slot - 1].do_lookup = 0;
1354 eqn->atts_table[slot - 1].use_codepoint = 1;
1355 }
1356
1357 slot++;
1358 }
1359 }
1360
1361 /* parse the equation header and fill the fields of eqn */
Eqn_Create(MTEquation * eqn,unsigned char * eqn_stream,int eqn_size)1362 int Eqn_Create(MTEquation * eqn, unsigned char *eqn_stream, int eqn_size)
1363 {
1364 int src_index = 0;
1365
1366 eqn->indent[0] = '%';
1367 eqn->indent[1] = 0;
1368 eqn->o_list = NULL;
1369 eqn->atts_table = NULL;
1370 eqn->m_mode = EQN_MODE_TEXT;
1371 eqn->m_inline = 0;
1372 eqn->m_latex_start = NULL;
1373 eqn->m_latex_end = NULL;
1374 eqn->m_latex = NULL;
1375 eqn->m_mtef_ver = 0;
1376
1377 if (g_input_file_type != TYPE_RAWEQN) {
1378 eqn->m_mtef_ver = eqn_stream[0];
1379 src_index++;
1380 } else {
1381 fprintf(stderr, "skipping 0x %02X %02X %02X %02X\n", eqn_stream[0], eqn_stream[1], eqn_stream[2], eqn_stream[3]);
1382 src_index+=4;
1383 }
1384
1385 switch (eqn->m_mtef_ver) {
1386 case 0:
1387 eqn->m_mtef_ver = 5;
1388 eqn->m_product = 0;
1389 eqn->m_version = 0;
1390 eqn->m_version_sub = 0;
1391 break;
1392 case 1:
1393 case 101:
1394 eqn->m_platform = (eqn->m_mtef_ver == 101) ? 1 : 0;
1395 eqn->m_product = 0;
1396 eqn->m_version = 1;
1397 eqn->m_version_sub = 0;
1398 break;
1399
1400 case 2:
1401 case 3:
1402 case 4:
1403 eqn->m_platform = eqn_stream[src_index++];
1404 eqn->m_product = eqn_stream[src_index++];
1405 eqn->m_version = eqn_stream[src_index++];
1406 eqn->m_version_sub = eqn_stream[src_index++];
1407 break;
1408
1409 case 5:
1410 eqn->m_platform = eqn_stream[src_index++];
1411 eqn->m_product = eqn_stream[src_index++];
1412 eqn->m_version = eqn_stream[src_index++];
1413 eqn->m_version_sub = eqn_stream[src_index++];
1414
1415 /* the application key is a null terminated string */
1416 while (eqn_stream[src_index]) {
1417 // fprintf(stderr, "%d", eqn_stream[src_index]);
1418 src_index++;
1419 if (src_index == eqn_size) {
1420 RTFMsg("The Application Key for the Equation is screwy!");
1421 return (false);
1422 }
1423 }
1424 /* fprintf(stderr, "\n"); */
1425 src_index++;
1426
1427 eqn->m_inline = eqn_stream[src_index++];
1428 break;
1429
1430 default:
1431 RTFMsg("* Unsupported MathType Equation Binary Format (MTEF=%d)\n",
1432 eqn->m_mtef_ver);
1433 return (false);
1434 }
1435
1436 if (g_input_file_type==TYPE_EQN || DEBUG_EQUATION) {
1437 fprintf(stderr,"* MTEF ver = %d\n", eqn->m_mtef_ver);
1438 fprintf(stderr,"* Platform = %s\n", (eqn->m_platform == PLATFORM_WIN) ? "Win" : "Mac");
1439 fprintf(stderr,"* Product = %s\n", (eqn->m_product) ? "MathType" : "EqnEditor");
1440 fprintf(stderr,"* Version = %d.%d\n", eqn->m_version, eqn->m_version_sub);
1441 fprintf(stderr,"* Type = %s (ignored because it is unreliable)\n", eqn->m_inline ? "inline" : "display");
1442 }
1443
1444 eqn->m_atts_table = Profile_MT_CHARSET_ATTS;
1445 Eqn_LoadCharSetAtts(eqn, Profile_MT_CHARSET_ATTS);
1446 eqn->m_char_table = Profile_CHARTABLE;
1447
1448 /* We expect a SIZE then a LINE or PILE */
1449 eqn->o_list = Eqn_GetObjectList(eqn, eqn_stream, &src_index, 2);
1450
1451 return (true);
1452 }
1453
1454 /* formatting routines. convert internal form to LaTeX */
1455
1456
1457
1458 static
Eqn_TranslateRULER(MTEquation * eqn,MT_RULER * ruler)1459 char *Eqn_TranslateRULER(MTEquation * eqn, MT_RULER * ruler)
1460 {
1461 char buf[128];
1462 EQ_STRREC strs[2];
1463 int num_strs = 0;
1464
1465 if (eqn->log_level >= 2) {
1466 snprintf(buf, 128, "\n%sRULER\n", eqn->indent);
1467 SetComment(strs, 2, buf);
1468 num_strs++;
1469 }
1470
1471 strcat(eqn->indent, " ");
1472
1473 /* no translation implemented yet */
1474
1475 eqn->indent[strlen(eqn->indent) - 2] = 0;
1476
1477 return Eqn_JoinStrings(eqn, strs, num_strs);
1478 }
1479
1480 static
Eqn_TranslateLINE(MTEquation * eqn,MT_LINE * line)1481 char *Eqn_TranslateLINE(MTEquation * eqn, MT_LINE * line)
1482 {
1483 char buf[128];
1484 char *thetex;
1485 EQ_STRREC strs[3];
1486
1487 int num_strs = 0;
1488 if (eqn->log_level >= 2) {
1489 snprintf(buf, 128, "\n%sLINE\n", eqn->indent);
1490 SetComment(strs, 2, buf);
1491 num_strs++;
1492 }
1493
1494 strcat(eqn->indent, " ");
1495
1496 if (line->ruler) {
1497 // fprintf(stderr,"LINE---ruler\n");
1498 strs[num_strs].log_level = 0;
1499 strs[num_strs].do_delete = 1;
1500 strs[num_strs].ilk = Z_TEX;
1501 strs[num_strs].is_line = 0;
1502 strs[num_strs].data = Eqn_TranslateRULER(eqn, line->ruler);
1503 num_strs++;
1504 }
1505
1506 if (line->object_list) {
1507 // fprintf(stderr,"LINE---object list\n");
1508 strs[num_strs].log_level = 0;
1509 strs[num_strs].do_delete = 1;
1510 strs[num_strs].ilk = Z_TEX;
1511 strs[num_strs].is_line = 0;
1512 strs[num_strs].data = Eqn_TranslateObjects(eqn, line->object_list);
1513 num_strs++;
1514 }
1515
1516 eqn->indent[strlen(eqn->indent) - 2] = 0;
1517
1518 thetex = Eqn_JoinStrings(eqn, strs, num_strs);
1519
1520 if (g_input_file_type==TYPE_EQN || DEBUG_LINE) fprintf(stderr,"LINE='%s'\n",thetex);
1521 return thetex;
1522 }
1523
1524 /* Character translation, MathType to TeX, using inifile data */
1525
1526 static
Eqn_GetTexChar(MTEquation * eqn,EQ_STRREC * strs,MT_CHAR * thechar,int * math_attr)1527 int Eqn_GetTexChar(MTEquation * eqn, EQ_STRREC * strs, MT_CHAR * thechar, int *math_attr)
1528 {
1529 MT_CHARSET_ATTS set_atts;
1530 MT_EMBELL *embells;
1531 char buff[256];
1532 int num_strs = 0;
1533
1534 char *ztex = (char *) NULL;
1535 char zch = 0;
1536 char *zdata = (char *) NULL;
1537
1538 if (DEBUG_CHAR) fprintf(stderr,"in GetTeXChar seeking eqn->atts_table[%d]\n",(int) thechar->typeface - 129);
1539
1540 strs[0].log_level = 0;
1541 strs[0].do_delete = 1;
1542 strs[0].ilk = Z_TEX;
1543 strs[0].is_line = 0;
1544 strs[0].data = NULL;
1545
1546 if (thechar->typeface >= 129 && thechar->typeface < 129 + NUM_TYPEFACE_SLOTS) {
1547 set_atts = eqn->atts_table[thechar->typeface - 129];
1548 } else { /* unexpected charset */
1549 char buffer[16];
1550 char key[16];
1551 uint32_t zln;
1552 snprintf(key, 16, "%d", (int) thechar->typeface);
1553 zln = GetProfileStr(eqn->m_atts_table, key, buffer, 16);
1554 if (zln) {
1555 set_atts.mathattr = buffer[0] - '0';
1556 set_atts.do_lookup = buffer[2] - '0';
1557 set_atts.use_codepoint = buffer[4] - '0';
1558 } else {
1559 set_atts.mathattr = 1;
1560 set_atts.do_lookup = 1;
1561 set_atts.use_codepoint = 1;
1562 }
1563 }
1564
1565 *math_attr = set_atts.mathattr;
1566 if (set_atts.do_lookup) {
1567 uint32_t zln;
1568 char key[16]; /* 132.65m */
1569
1570 snprintf(key, 16, "%d.%d", (int)thechar->typeface, (int)thechar->character);
1571 if (DEBUG_CHAR) fprintf(stderr, "looking up char in table[%d] as %d.%d\n",
1572 (int)thechar->typeface - 129, (int) thechar->typeface, (int) thechar->character);
1573
1574 if (*math_attr == 3) {
1575 if (eqn->m_mode == EQN_MODE_TEXT)
1576 strcat(key, "t");
1577 else
1578 strcat(key, "m");
1579 *math_attr = 0;
1580 }
1581
1582 zln = GetProfileStr(eqn->m_char_table, key, buff, 256);
1583 if (zln) {
1584 ztex = (char *) malloc(zln + 1);
1585 strcpy(ztex, buff);
1586 }
1587 }
1588
1589 if (*math_attr == MA_FORCE_MATH && eqn->m_mode == EQN_MODE_TEXT) {
1590 setMathMode(eqn, eqn->m_inline ? EQN_MODE_INLINE : EQN_MODE_DISPLAY);
1591
1592 } else if (*math_attr == MA_FORCE_TEXT) {
1593 setMathMode(eqn, EQN_MODE_TEXT);
1594 }
1595 if (!ztex && set_atts.use_codepoint) {
1596 if (thechar->character >= 32 && thechar->character <= 127) {
1597 zch = (char) thechar->character;
1598 if (thechar->character == 38) {
1599 snprintf(buff,20,"\\&");
1600 ztex = (char *) malloc(strlen(buff) + 1);
1601 strcpy(ztex, buff);
1602 }
1603 if (thechar->typeface == 135) {
1604 snprintf(buff,20,"\\mathbf{%c}", zch);
1605 ztex = (char *) malloc(strlen(buff) + 1);
1606 strcpy(ztex, buff);
1607 }
1608 }
1609 }
1610
1611 if (ztex) {
1612 zdata = ztex;
1613 } else if (zch) {
1614 zdata = (char *) malloc(2);
1615 zdata[0] = zch;
1616 zdata[1] = 0;
1617 }
1618
1619 if (!zdata)
1620 return num_strs;
1621
1622 embells = thechar->embellishment_list;
1623
1624 while (embells) {
1625 char template[128];
1626 *template = '\0';
1627
1628 /* template will in the form "math template,text template" */
1629 if (embells->embell>1 && embells->embell<37)
1630 strcpy(template, Template_EMBELLS[embells->embell]);
1631
1632 if (DEBUG_EMBELLS || g_input_file_type==TYPE_EQN)
1633 fprintf(stderr,"Yikes --- Template_EMBELLS[%d]='%s'!\n", (int) embells->embell,template);
1634
1635 if (strlen(template)) { /* only bother if there is a character */
1636 char *join, *t_ptr, *j_ptr;
1637
1638 t_ptr = strchr(template, ',');
1639
1640 if (!t_ptr) {
1641 RTFPanic("Malformed EMBELL Template!\n");
1642 exit(1);
1643 }
1644
1645 /* set string to first or second half of template depending on mode */
1646 if (eqn->m_mode != EQN_MODE_TEXT) {
1647 *t_ptr = '\0';
1648 t_ptr = template;
1649 } else
1650 t_ptr++;
1651
1652 join = (char *) malloc(strlen(t_ptr) + strlen(zdata) + 16);
1653 j_ptr = join;
1654
1655 if (DEBUG_EMBELLS || g_input_file_type==TYPE_EQN) fprintf(stderr,"Yikes --- replacement template is '%s'!\n",t_ptr);
1656
1657 /* replace %1 in template with zdata */
1658 while (*t_ptr) {
1659 if (*t_ptr == '%') {
1660 t_ptr+=2; /* skip over %1 */
1661 strcpy(j_ptr, zdata);
1662 j_ptr += strlen(zdata);
1663 } else {
1664 *j_ptr = *t_ptr;
1665 j_ptr++;
1666 t_ptr++;
1667 }
1668 }
1669 *j_ptr = '\0';
1670 free(zdata);
1671 zdata = join;
1672 }
1673 if (DEBUG_EMBELLS || g_input_file_type==TYPE_EQN) fprintf(stderr,"Yikes --- after replacement strs[0].data is '%s'!\n",zdata);
1674
1675 embells = (MT_EMBELL *) embells->next;
1676 }
1677
1678 strs[0].data = zdata;
1679 num_strs++;
1680 return num_strs;
1681 }
1682
1683 static
Eqn_TranslateCHAR(MTEquation * eqn,MT_CHAR * thechar)1684 char *Eqn_TranslateCHAR(MTEquation * eqn, MT_CHAR * thechar)
1685 {
1686 EQ_STRREC strs[4];
1687 int num_strs = 0;
1688 int math_attr;
1689
1690 if (eqn->log_level >= 2) {
1691 char buf[128];
1692 snprintf(buf, 128, "\n%sCHAR : atts=%d,typeface=%d,char=%c,%d\n",
1693 eqn->indent, (int)thechar->atts, (int)thechar->typeface,
1694 (char) thechar->character, (int)thechar->character);
1695 SetComment(strs, 2, buf);
1696 num_strs++;
1697 }
1698 if (DEBUG_CHAR || g_input_file_type==TYPE_EQN)
1699 fprintf(stderr, "CHAR : atts=%d,typeface=%3d=%10s, char='%c' = 0x%04x = %d\n",
1700 (int)thechar->atts, (int)thechar->typeface, typeFaceName[thechar->typeface-128],
1701 (char) thechar->character, (unsigned int)thechar->character, (int)thechar->character);
1702 /*
1703 SetComment(strs + num_strs, 100, (char *) NULL);
1704 num_strs++;
1705 */
1706 strcat(eqn->indent, " ");
1707
1708 num_strs += Eqn_GetTexChar(eqn, strs + num_strs, thechar, &math_attr);
1709
1710 eqn->indent[strlen(eqn->indent) - 2] = 0;
1711
1712 return Eqn_JoinStrings(eqn, strs, num_strs);
1713 }
1714
1715
1716 static
Eqn_TranslateFUNCTION(MTEquation * eqn,MT_OBJLIST * curr_node,int * advance)1717 char *Eqn_TranslateFUNCTION(MTEquation * eqn, MT_OBJLIST * curr_node,
1718 int *advance)
1719 {
1720 char nom[16];
1721 char tex_func[128];
1722 EQ_STRREC strs[4];
1723 int num_strs = 0;
1724 uint32_t zlen;
1725 char *zdata;
1726
1727 /* step through object list to gather the function name */
1728 *advance = 0;
1729 nom[*advance] = '\0';
1730 while (curr_node && curr_node->tag == CHAR) {
1731 MT_CHAR *charptr = (MT_CHAR *) curr_node->obj_ptr;
1732 if (!charptr || charptr->typeface != 130 || !isalpha((int) charptr->character))
1733 break;
1734
1735 nom[*advance] = (char) charptr->character;
1736 curr_node = (MT_OBJLIST *) curr_node->next;
1737 (*advance)++;
1738 }
1739 nom[*advance] = '\0';
1740
1741 if (*advance == 0) return NULL;
1742
1743 if (g_input_file_type==TYPE_EQN || DEBUG_FUNCTION) fprintf(stderr,"FUNC : name = '%s'\n", nom);
1744
1745 zlen = GetProfileStr(Profile_FUNCTIONS, nom, tex_func, 128);
1746
1747 /* no function translation found, just emit these characters */
1748 if (!zlen || !tex_func[0])
1749 snprintf(tex_func,128,"\\mathrm{%s}", nom);
1750
1751 if (eqn->log_level >= 2) {
1752 char buf[128];
1753 snprintf(buf, 128, "\n%sFUNCTION : %s\n", eqn->indent, nom);
1754 SetComment(strs, 2, buf);
1755 num_strs++;
1756 }
1757
1758 /* place_holder for $ if needed
1759 SetComment(strs + num_strs, 100, (char *) NULL);
1760 num_strs++;
1761 */
1762 strs[num_strs].log_level = 0;
1763 strs[num_strs].do_delete = 1;
1764 strs[num_strs].ilk = Z_TEX;
1765 strs[num_strs].is_line = 0;
1766 zdata = (char *) malloc(strlen(tex_func) + 1);
1767 strcpy(zdata, tex_func);
1768 strs[num_strs].data = zdata;
1769 num_strs++;
1770
1771 return Eqn_JoinStrings(eqn, strs, num_strs);
1772 }
1773
1774
1775 static
Eqn_TranslateTEXTRUN(MTEquation * eqn,MT_OBJLIST * curr_node,int * advance)1776 char *Eqn_TranslateTEXTRUN(MTEquation * eqn, MT_OBJLIST * curr_node,
1777 int *advance)
1778 {
1779 /* Gather the tex run */
1780
1781 int di = 0;
1782 char run[256];
1783 EQ_STRREC strs[4];
1784 int num_strs = 0;
1785 char tbuff[256];
1786 uint32_t zlen;
1787 char *zdata;
1788 char *ndl;
1789
1790 *advance = 0;
1791
1792 while (curr_node && (curr_node->tag == CHAR || curr_node->tag == SIZE)) {
1793 if (curr_node->tag == CHAR) {
1794 MT_CHAR *charptr = (MT_CHAR *) curr_node->obj_ptr;
1795 if (charptr && charptr->typeface == 129) {
1796 run[di++] = (char) charptr->character;
1797 curr_node = (MT_OBJLIST *) curr_node->next;
1798 (*advance)++;
1799 } else
1800 break;
1801 } else {
1802 curr_node = (MT_OBJLIST *) curr_node->next;
1803 (*advance)++;
1804 }
1805 }
1806 run[di] = 0;
1807
1808 if (eqn->log_level >= 2) {
1809 char buf[256];
1810 snprintf(buf, 256, "\n%sTEXTRUN : %s\n", eqn->indent, run);
1811 SetComment(strs, 2, buf);
1812 num_strs++;
1813 }
1814
1815 strs[num_strs].log_level = 0;
1816 strs[num_strs].do_delete = 1;
1817 strs[num_strs].ilk = Z_TEX;
1818 strs[num_strs].is_line = 0;
1819
1820 zlen = GetProfileStr(Profile_TEMPLATES, "TextInMath", tbuff, 256);
1821 if (zlen <= 0)
1822 strcpy(tbuff, "\\text{#1}");
1823
1824 zdata = malloc(di + zlen);
1825
1826 ndl = strchr(tbuff, '#');
1827 if (ndl) {
1828 *ndl = 0;
1829 strcpy(zdata, tbuff);
1830 } else
1831 *zdata = 0;
1832 strcat(zdata, run);
1833 if (ndl) {
1834 ndl += 2;
1835 strcat(zdata, ndl);
1836 }
1837
1838 strs[num_strs].data = zdata;
1839 num_strs++;
1840
1841 return Eqn_JoinStrings(eqn, strs, num_strs);
1842 }
1843
1844 #if 0
1845 /* Line positions are stored in a 2-bit pieces in the bits
1846 * array. This extracts the right one and returns true if
1847 * a dashed, dotted, or solid line is present.
1848 */
1849 static
1850 int HasHVLine(int line_num, unsigned char *bits)
1851 {
1852
1853 int rv = 0;
1854 int byte_num = line_num / 4;
1855 int shift = (line_num % 4) * 2;
1856 int mask = 0x03 << shift;
1857
1858 if (byte_num < MATR_MAX)
1859 rv = (bits[byte_num] & mask) ? 1 : 0;
1860
1861 return rv;
1862 }
1863 #endif
1864
1865 /* The current implementation ignores the vertical and
1866 * horizontal lines ... it is not clear if it makes any
1867 * sense to use the tabular environment to include this
1868 * feature
1869 */
1870 static
Eqn_TranslateMATRIX(MTEquation * eqn,MT_MATRIX * matrix)1871 char *Eqn_TranslateMATRIX(MTEquation * eqn, MT_MATRIX * matrix)
1872 {
1873 size_t buf_limit = 8192;
1874 char *thetex, *cell;
1875 char *col_align = "c";
1876 uint8_t j,col,row;
1877 MT_OBJLIST *obj_list;
1878
1879 thetex = malloc(buf_limit);
1880 *thetex = 0;
1881
1882 if (eqn->log_level >= 2) {
1883 char buf[128];
1884 snprintf(buf, 128, "\n%sStart MATRIX\n", eqn->indent);
1885 strcat(thetex, buf);
1886 }
1887
1888 strcat(eqn->indent, " ");
1889
1890 strcat(thetex, "\n\\begin{array}");
1891
1892 /* set the vertical alignment of the matrix */
1893 if (matrix->valign == 0)
1894 strcat(thetex, "[t]");
1895 else if (matrix->valign == 2)
1896 strcat(thetex, "[b]");
1897
1898 /* set alignment for all columns */
1899 if (matrix->h_just == MT_LEFT)
1900 col_align = "l";
1901 else if (matrix->h_just == MT_RIGHT)
1902 col_align = "r";
1903
1904 strcat(thetex, "{");
1905 for (col=0; col<matrix->cols; col++)
1906 strcat(thetex, col_align);
1907 strcat(thetex, "}\n");
1908
1909 obj_list = matrix->element_list;
1910 for (row = 0; row < matrix->rows; row++) {
1911
1912 if (row > 0)
1913 strcat(thetex, " \\\\\n");
1914
1915 for (col=0; col<matrix->cols; col++) {
1916
1917 if (col>0) strcat(thetex, " & ");
1918
1919 while (obj_list && obj_list->tag != LINE)
1920 obj_list = (MT_OBJLIST *) obj_list->next;
1921
1922 /* no column element found ... finish the line and exit */
1923 if (!obj_list || obj_list->tag != LINE) {
1924 for (j=col; j<matrix->cols; j++)
1925 strcat(thetex, " & ");
1926 break;
1927 }
1928
1929 cell = Eqn_TranslateLINE(eqn, (MT_LINE *) obj_list->obj_ptr);
1930 strcat(thetex, cell);
1931 free(cell);
1932
1933 obj_list = (MT_OBJLIST *) obj_list->next;
1934 }
1935 } /* loop down rows */
1936
1937 strcat(thetex, "\n\\end{array}\n");
1938
1939 eqn->indent[strlen(eqn->indent) - 2] = 0;
1940
1941 if (eqn->log_level >= 2) {
1942 char buf[128];
1943 snprintf(buf, 128, "\n%sEnd MATRIX\n", eqn->indent);
1944 strcat(thetex, buf);
1945 }
1946 return thetex;
1947 }
1948
1949 static
Is_RelOp(MT_CHAR * charptr)1950 int Is_RelOp(MT_CHAR * charptr)
1951 {
1952
1953 int rv = 0;
1954
1955 if (charptr->typeface == 134) {
1956
1957 if (charptr->character == 60 || charptr->character == 62
1958 || charptr->character == 163 || charptr->character == 179
1959 || charptr->character == 185 || charptr->character == 186
1960 || charptr->character == 187 || charptr->character == 64
1961 || charptr->character == 61 || charptr->character == 181)
1962 rv = 1;
1963
1964 } else if (charptr->typeface == 139) {
1965 if (charptr->character == 112 || charptr->character == 102
1966 || charptr->character == 60 || charptr->character == 62)
1967 rv = 1;
1968 }
1969
1970 return rv;
1971 }
1972
1973
1974 static
Eqn_TranslateEQNARRAY(MTEquation * eqn,MT_PILE * pile)1975 char *Eqn_TranslateEQNARRAY(MTEquation * eqn, MT_PILE * pile)
1976 {
1977 char *rv;
1978 uint32_t buf_limit = 8192;
1979 MT_OBJLIST *obj_list;
1980 int curr_row = 0;
1981 int right_only = 0;
1982 char *data;
1983 uint32_t b_off;
1984
1985 rv = malloc(buf_limit);
1986 *rv = 0;
1987
1988 if (eqn->log_level >= 2) {
1989 char buf[128];
1990 snprintf(buf, 128, "\n%sStart EQNARRAY\n", eqn->indent);
1991 strcat(rv, buf);
1992 }
1993
1994 strcat(eqn->indent, " ");
1995
1996 setMathMode(eqn, EQN_MODE_EQNARRAY);
1997
1998 obj_list = pile->line_list;
1999
2000 while (obj_list) { /* loop down lines */
2001
2002 if (curr_row)
2003 strcat(rv, " \\\\\n");
2004
2005 while (obj_list && obj_list->tag != LINE) { /* could be a SIZE */
2006 obj_list = (MT_OBJLIST *) obj_list->next;
2007 }
2008
2009 if (obj_list && obj_list->tag == LINE) {
2010
2011 /* locate the "relop" in the object_list of the current line */
2012
2013 MT_OBJLIST *left_node = (MT_OBJLIST *) NULL;
2014 MT_OBJLIST *right_node = (MT_OBJLIST *) NULL;
2015
2016 MT_LINE *line = (MT_LINE *) obj_list->obj_ptr;
2017 MT_OBJLIST *curr_node = line->object_list;
2018 while (curr_node) {
2019 if (curr_node->tag == CHAR) { /* check for a relop */
2020 if (Is_RelOp((MT_CHAR *) curr_node->obj_ptr))
2021 break;
2022 }
2023 left_node = curr_node;
2024 curr_node = (MT_OBJLIST *) curr_node->next;
2025 }
2026
2027 /* handle left side */
2028
2029 if (left_node) {
2030 if (curr_node) {
2031 left_node->next = NULL;
2032 data = Eqn_TranslateLINE(eqn, (MT_LINE *) obj_list->obj_ptr);
2033
2034 b_off = (uint32_t) strlen(rv);
2035 rv = ToBuffer(data, rv, &b_off, &buf_limit); /* strcat( rv,data ); */
2036
2037 left_node->next = (void *) curr_node;
2038 } else {
2039 right_node = left_node;
2040 right_only = 1;
2041 }
2042 }
2043 strcat(rv, " & ");
2044
2045 /* handle the relop */
2046
2047 if (curr_node) {
2048 char *data2 = Eqn_TranslateCHAR(eqn, (MT_CHAR *) curr_node->obj_ptr);
2049 strcat(rv, data2);
2050 free(data2);
2051 right_node = (MT_OBJLIST *) curr_node->next;
2052 }
2053 strcat(rv, " & ");
2054
2055 /* handle right side */
2056
2057 if (right_node) {
2058 char *data2;
2059 if (right_only)
2060 data2 = Eqn_TranslateLINE(eqn, (MT_LINE *) obj_list->obj_ptr);
2061 else
2062 data2 = Eqn_TranslateObjects(eqn, right_node);
2063
2064 b_off = (uint32_t) strlen(rv);
2065 rv = ToBuffer(data2, rv, &b_off, &buf_limit); /* strcat( rv,data ); */
2066 }
2067
2068 obj_list = (MT_OBJLIST *) obj_list->next;
2069 } else
2070 break;
2071
2072 curr_row++;
2073 } /* loop down thru lines */
2074
2075 eqn->indent[strlen(eqn->indent) - 2] = 0;
2076
2077 if (eqn->log_level >= 2) {
2078 char buf[128];
2079 snprintf(buf, 128, "%sEnd EQNARRAY\n", eqn->indent);
2080 strcat(rv, buf);
2081 }
2082
2083 return rv;
2084 }
2085
2086
2087 static
Eqn_TranslateTABULAR(MTEquation * eqn,MT_PILE * pile)2088 char *Eqn_TranslateTABULAR(MTEquation * eqn, MT_PILE * pile)
2089 {
2090 MT_OBJLIST *obj_list;
2091 size_t buf_limit = 8192;
2092 uint8_t row;
2093 uint32_t head_len;
2094 char *thetex, *line;
2095
2096 thetex = (char *) malloc(buf_limit);
2097
2098 /* fprintf(stderr, "PILE : Translating Tabular PILE\n"); */
2099 *thetex = '\0';
2100
2101 if (eqn->log_level >= 2) {
2102 char buf[128];
2103 snprintf(buf, 128, "\n%sStart TABULAR\n", eqn->indent);
2104 strcat(thetex, buf);
2105 }
2106
2107 strcat(eqn->indent, " ");
2108
2109 strcat(thetex, "\n\\begin{array}");
2110
2111 switch (pile->valign) {
2112 case PVA_TOP:
2113 strcat(thetex, "[t]");
2114 break;
2115 case PVA_BOTTOM:
2116 strcat(thetex, "[b]");
2117 break;
2118 case PVA_CENTER:
2119 case PVA_CENTERING:
2120 case PVA_MATH:
2121 break;
2122 }
2123
2124 switch (pile->halign) {
2125 case MT_PILE_LEFT:
2126 strcat(thetex, "{l}\n");
2127 break;
2128 case MT_PILE_RIGHT:
2129 strcat(thetex, "{r}\n");
2130 break;
2131 case MT_PILE_CENTER:
2132 case MT_PILE_OPERATOR:
2133 case MT_PILE_DECIMAL:
2134 strcat(thetex, "{r}\n");
2135 break;
2136 }
2137
2138 head_len = (uint32_t) strlen(thetex);
2139
2140 row = 1;
2141 for (obj_list = pile->line_list; obj_list != NULL; obj_list = (MT_OBJLIST *)obj_list->next) {
2142
2143 if (obj_list->tag != LINE)
2144 continue;
2145
2146 line = Eqn_TranslateLINE(eqn, (MT_LINE *) obj_list->obj_ptr);
2147
2148 if (strlen(line)>0) {
2149 if (row > 1) strcat(thetex, " \\\\\n"); /* end previous row */
2150 strcat(thetex, line);
2151 row++;
2152 }
2153 free(line);
2154 }
2155
2156 if (row==2 && strlen(thetex) > head_len)
2157 strcat(thetex, "\n");
2158 strcat(thetex, "\\end{array}\n");
2159
2160 eqn->indent[strlen(eqn->indent) - 2] = 0;
2161
2162 if (eqn->log_level >= 2) {
2163 char buf[128];
2164 snprintf(buf, 128, "\n%sEnd TABULAR\n", eqn->indent);
2165 strcat(thetex, buf);
2166 }
2167
2168 return thetex;
2169 }
2170
2171
2172 static
Eqn_TranslatePILEtoTARGET(MTEquation * eqn,MT_PILE * pile,char * targ_nom)2173 char *Eqn_TranslatePILEtoTARGET(MTEquation * eqn, MT_PILE * pile, char *targ_nom)
2174 {
2175 MT_OBJLIST *obj_list;
2176 char ini_line[256];
2177 uint32_t dlen = 0;
2178 /*int forces_math = 1;*/
2179 /*int forces_text = 0;*/
2180 char *head = "";
2181 char *line_sep = " \\\\ ";
2182 char *tail = "";
2183 uint32_t buf_limit = 8192;
2184 int curr_row = 0;
2185
2186 char *rv = (char *) malloc(buf_limit);
2187 *rv = 0;
2188
2189 if (targ_nom && *targ_nom)
2190 dlen = GetProfileStr(Profile_PILEtranslation, targ_nom, ini_line, 256);
2191
2192 /* ini_line = "TextOnly,\begin{env}, \\,\end{env}" */
2193
2194 if (dlen) {
2195 char *rover = ini_line;
2196 if (*rover == 'T') {
2197 /* forces_math = 0; */
2198 /* forces_text = 1; */
2199 }
2200 rover = strchr(rover, ','); /* end math/text force flag */
2201 if (rover && *(rover + 1)) {
2202 rover++; /* start of head */
2203 if (*rover != ',')
2204 head = rover;
2205 rover = strchr(rover, ','); /* end of head */
2206 if (rover) {
2207 *rover = 0;
2208 rover++; /* start of line_sep */
2209 if (*rover && *(rover + 1)) {
2210 if (*rover != ',')
2211 line_sep = rover;
2212 rover = strchr(rover, ','); /* end of line_sep */
2213 if (rover) {
2214 *rover = 0;
2215 rover++; /* start of tail */
2216 if (*rover)
2217 if (*rover != ',')
2218 tail = rover;
2219 }
2220 }
2221 }
2222 }
2223 }
2224
2225 if (eqn->log_level >= 2) {
2226 char buf[128];
2227 snprintf(buf, 128, "\n%sStart PILE in TMPL field\n", eqn->indent);
2228 strcat(rv, buf);
2229 }
2230
2231 strcat(eqn->indent, " ");
2232
2233 strcat(rv, "\n");
2234 strcat(rv, head);
2235 strcat(rv, "\n");
2236
2237 obj_list = pile->line_list;
2238
2239 while (obj_list) { /* loop down thru lines */
2240
2241 if (curr_row) {
2242 strcat(rv, line_sep);
2243 strcat(rv, "\n");
2244 }
2245
2246 while (obj_list && obj_list->tag != LINE) { /* could be a SIZE */
2247 obj_list = (MT_OBJLIST *) obj_list->next;
2248 }
2249
2250 if (obj_list && obj_list->tag == LINE) {
2251 char *data = Eqn_TranslateLINE(eqn, (MT_LINE *) obj_list->obj_ptr);
2252
2253 uint32_t b_off = (uint32_t) strlen(rv);
2254 rv = ToBuffer(data, rv, &b_off, &buf_limit);
2255
2256 obj_list = (MT_OBJLIST *) obj_list->next;
2257 } else
2258 break;
2259
2260 curr_row++;
2261 } /* loop down thru lines */
2262
2263 /* put "\n\\end{array*}\n" */
2264
2265 strcat(rv, "\n");
2266 strcat(rv, tail);
2267 strcat(rv, "\n");
2268
2269 eqn->indent[strlen(eqn->indent) - 2] = 0;
2270
2271 if (eqn->log_level >= 2) {
2272 char buf[128];
2273 snprintf(buf, 128, "\n%sEnd PILE in TMPL field\n", eqn->indent);
2274 strcat(rv, buf);
2275 }
2276
2277 return rv;
2278 }
2279
2280
2281 static
Eqn_TranslateSIZE(MTEquation * eqn,MT_SIZE * size)2282 char *Eqn_TranslateSIZE(MTEquation * eqn, MT_SIZE * size)
2283 {
2284
2285 EQ_STRREC strs[2];
2286
2287 int num_strs = 0;
2288 if (eqn->log_level >= 2) {
2289 char buf[128];
2290 snprintf(buf, 128, "\n%sSIZE\n", eqn->indent);
2291 SetComment(strs, 2, buf);
2292 num_strs++;
2293 }
2294 if (DEBUG_SIZE) fprintf(stderr, "\n%sSIZE type=%d, lsize=%d, dsize=%d\n", eqn->indent, size->type, size->lsize, size->dsize);
2295
2296 strcat(eqn->indent, " ");
2297
2298 /* not translation implemented yet */
2299
2300 eqn->indent[strlen(eqn->indent) - 2] = 0;
2301
2302 return Eqn_JoinStrings(eqn, strs, num_strs);
2303 }
2304
2305
2306 static
Eqn_TranslateFONT(MTEquation * eqn,MT_FONT * font)2307 char *Eqn_TranslateFONT(MTEquation * eqn, MT_FONT * font)
2308 {
2309
2310 EQ_STRREC strs[2];
2311 int num_strs = 0;
2312
2313 if (eqn->log_level >= 2) {
2314 char buf[128];
2315 snprintf(buf, 128,"\n%sFONT\n", eqn->indent);
2316 SetComment(strs, 2, buf);
2317 num_strs++;
2318 }
2319
2320 strcat(eqn->indent, " ");
2321
2322 /* no translation implemented yet */
2323
2324 eqn->indent[strlen(eqn->indent) - 2] = 0;
2325
2326 return Eqn_JoinStrings(eqn, strs, num_strs);
2327 }
2328
2329 static
GetPileType(char * the_template,int arg_num,char * targ_nom)2330 void GetPileType(char *the_template, int arg_num, char *targ_nom)
2331 {
2332 int di = 0;
2333 char *ptr;
2334 char tok[4];
2335 snprintf(tok, 4, "#%d", arg_num); /* #2 */
2336
2337 ptr = strstr(the_template, tok);
2338 if (ptr && *(ptr + 2) == '[') {
2339 ptr += 3;
2340 while (*ptr != ']' && di < 32)
2341 targ_nom[di++] = *ptr++;
2342 }
2343
2344 targ_nom[di] = 0;
2345 }
2346
2347
2348 static
Eqn_GetTmplStr(MTEquation * eqn,uint8_t selector,uint16_t variation,EQ_STRREC * strs)2349 int Eqn_GetTmplStr(MTEquation * eqn, uint8_t selector, uint16_t variation, EQ_STRREC * strs)
2350 {
2351 char key[16]; /* key = "20.1" */
2352 char ini_line[256];
2353 char *tmpl_ptr;
2354 int result;
2355 int num_strs = 0; /* this becomes the return value */
2356
2357 snprintf(key, 16, "%d.%d", (int)selector, (int)variation);
2358
2359 if (eqn->m_mtef_ver==5)
2360 result = GetProfileStr(Profile_TEMPLATES_5, key, ini_line, 256);
2361 else
2362 result = GetProfileStr(Profile_TEMPLATES, key, ini_line, 256);
2363
2364 if (!result) {
2365 fprintf(stderr, "TMPL key='%s' not found in version %d Profile_TEMPLATE\n",key,eqn->m_mtef_ver);
2366 exit(1);
2367 }
2368
2369 // fprintf(stderr,"ini_line='%s'\n", ini_line);
2370 tmpl_ptr = strchr(ini_line, ',');
2371
2372 if (eqn->log_level >= 2) {
2373 char buf[512];
2374 snprintf(buf, 512, "\n%sTMPL : %s=!%s!\n", eqn->indent, key, ini_line);
2375 SetComment(strs, 2, buf);
2376 num_strs++;
2377 }
2378 if (0) fprintf(stderr, "\n%sTMPL : %s=!%s!\n", eqn->indent, key, ini_line);
2379
2380 if (tmpl_ptr)
2381 *tmpl_ptr++ = 0;
2382
2383 if (tmpl_ptr && *tmpl_ptr) {
2384 char *ztmpl;
2385 strs[num_strs].log_level = 0;
2386 strs[num_strs].do_delete = 1;
2387 strs[num_strs].ilk = Z_TMPL;
2388 strs[num_strs].is_line = 0;
2389 ztmpl = (char *) malloc(strlen(tmpl_ptr) + 1);
2390 strcpy(ztmpl, tmpl_ptr);
2391 strs[num_strs].data = ztmpl;
2392 num_strs++;
2393 }
2394
2395 return num_strs;
2396 }
2397
2398
2399 static
Eqn_TranslateTMPL(MTEquation * eqn,MT_TMPL * tmpl)2400 char *Eqn_TranslateTMPL(MTEquation * eqn, MT_TMPL * tmpl)
2401 {
2402 EQ_STRREC strs[10];
2403 char *the_template;
2404 int tally = 1;
2405 int num_strs;
2406 MT_OBJLIST *obj_list;
2407
2408 if (eqn->m_mode == EQN_MODE_TEXT)
2409 setMathMode(eqn, eqn->m_inline ? EQN_MODE_INLINE : EQN_MODE_DISPLAY);
2410
2411 if (eqn->m_mtef_ver == 5 && (tmpl->selector != 9))
2412 tmpl->variation &= 0x000f;
2413
2414 if (DEBUG_TEMPLATE || g_input_file_type==TYPE_EQN)
2415 fprintf(stderr, "TMPL : selector = %d, variation=0x%04x (%d.%d)\n",
2416 (int) tmpl->selector, (unsigned int) tmpl->variation, (int) tmpl->selector, (int) tmpl->variation);
2417
2418 num_strs = Eqn_GetTmplStr(eqn, tmpl->selector, tmpl->variation, strs);
2419
2420 the_template = strs[num_strs - 1].data;
2421
2422 if (DEBUG_TEMPLATE || g_input_file_type==TYPE_EQN)
2423 fprintf(stderr,"TMPL : num_strs=%d, strs[%d].data='%s'\n",num_strs,num_strs-1,the_template);
2424
2425 strcat(eqn->indent, " ");
2426
2427 obj_list = tmpl->subobject_list;
2428
2429 if (obj_list && obj_list->tag == CHAR) {
2430
2431 /* translateCHAR( (MT_CHAR*)obj_list->obj_ptr ); */
2432
2433 obj_list = (MT_OBJLIST *) obj_list->next;
2434 }
2435
2436 if (obj_list && obj_list->tag >= SIZE && obj_list->tag <= SUBSYM) {
2437
2438 obj_list = (MT_OBJLIST *) obj_list->next;
2439 }
2440
2441 while (obj_list) {
2442 if (obj_list->tag == LINE) {
2443 if (DEBUG_TEMPLATE || g_input_file_type==TYPE_EQN) fprintf(stderr,"TMPL : LINE object\n");
2444 strs[num_strs].log_level = 0;
2445 strs[num_strs].do_delete = 1;
2446 strs[num_strs].ilk = Z_TEX;
2447 strs[num_strs].is_line = 1;
2448 strs[num_strs].data = Eqn_TranslateLINE(eqn, (MT_LINE *) obj_list->obj_ptr);
2449 if (DEBUG_TEMPLATE || g_input_file_type==TYPE_EQN) fprintf(stderr,"TMPL : strs[%d].data='%s'\n",num_strs,strs[num_strs].data);
2450 num_strs++;
2451 tally++;
2452 } else if (obj_list->tag == PILE) { /* This one is DIFFICULT!! */
2453 char targ_nom[32];
2454 if (DEBUG_TEMPLATE || g_input_file_type==TYPE_EQN) fprintf(stderr,"TMPL : PILE object, targ_nom=%s\n",targ_nom);
2455 strs[num_strs].log_level = 0;
2456 strs[num_strs].do_delete = 1;
2457 strs[num_strs].ilk = Z_TEX;
2458 strs[num_strs].is_line = 2;
2459
2460 GetPileType(the_template, tally, targ_nom);
2461
2462 strs[num_strs].data = Eqn_TranslatePILEtoTARGET(eqn, (MT_PILE *) obj_list-> obj_ptr, targ_nom);
2463 if (DEBUG_TEMPLATE || g_input_file_type==TYPE_EQN) fprintf(stderr,"PILE : strs[%d].data='%s'\n",num_strs,strs[num_strs].data);
2464
2465 num_strs++;
2466 tally++;
2467 }
2468
2469 obj_list = (MT_OBJLIST *) obj_list->next;
2470 }
2471
2472 /* There may be a SIZE at the end of the list */
2473
2474 eqn->indent[strlen(eqn->indent) - 2] = 0;
2475
2476 return Eqn_JoinStrings(eqn, strs, num_strs);
2477 }
2478
2479
2480 static
Eqn_TranslatePILE(MTEquation * eqn,MT_PILE * pile)2481 char *Eqn_TranslatePILE(MTEquation * eqn, MT_PILE * pile)
2482 {
2483 EQ_STRREC strs[2];
2484 int num_strs = 0;
2485
2486 /* fprintf(stderr, "PILE : Translating PILE\n"); */
2487
2488 if (eqn->log_level >= 2) {
2489 char buf[128];
2490 snprintf(buf, 128, "\n%sPILE\n", eqn->indent);
2491 SetComment(strs, 2, buf);
2492 num_strs++;
2493 }
2494
2495 strcat(eqn->indent, " ");
2496
2497 strs[num_strs].log_level = 0;
2498 strs[num_strs].do_delete = 1;
2499 strs[num_strs].ilk = Z_TEX;
2500 strs[num_strs].is_line = 0;
2501
2502 setMathMode(eqn, EQN_MODE_DISPLAY);
2503
2504 if (pile->halign == MT_PILE_OPERATOR)
2505 strs[num_strs].data = Eqn_TranslateEQNARRAY(eqn, pile);
2506 else
2507 strs[num_strs].data = Eqn_TranslateTABULAR(eqn, pile);
2508 num_strs++;
2509
2510 eqn->indent[strlen(eqn->indent) - 2] = 0;
2511
2512 return Eqn_JoinStrings(eqn, strs, num_strs);
2513 }
2514
2515 static
Eqn_TranslateObjects(MTEquation * eqn,MT_OBJLIST * the_list)2516 char *Eqn_TranslateObjects(MTEquation * eqn, MT_OBJLIST * the_list)
2517 {
2518
2519 char *zcurr;
2520 char *rv = (char *) malloc(1024);
2521 uint32_t di = 0;
2522 uint32_t lim = 1024;
2523
2524 MT_OBJLIST *curr_node;
2525 *rv = 0;
2526
2527 if (DEBUG_TRANSLATION || g_input_file_type==TYPE_EQN) fprintf(stderr,"new object list\n");
2528 while (the_list) {
2529
2530 curr_node = the_list;
2531 the_list = (void *) the_list->next;
2532
2533 zcurr = (char *) NULL;
2534
2535 if (DEBUG_TRANSLATION || g_input_file_type==TYPE_EQN) print_tag(curr_node->tag, 0);
2536
2537 switch (curr_node->tag) {
2538
2539 case LINE:{
2540 MT_LINE *line = (MT_LINE *) curr_node->obj_ptr;
2541 if (line)
2542 zcurr = Eqn_TranslateLINE(eqn, line);
2543 }
2544 break;
2545
2546 case CHAR:{
2547 int advance = 0;
2548 MT_CHAR *charptr = (MT_CHAR *) curr_node->obj_ptr;
2549 if (!charptr) break;
2550
2551 if (charptr->typeface == 130) { /* auto_recognize functions */
2552 zcurr = Eqn_TranslateFUNCTION(eqn, curr_node, &advance);
2553 while (advance > 1) {
2554 the_list = (MT_OBJLIST *) the_list->next;
2555 advance--;
2556 }
2557 } else if (charptr->typeface == 129 && eqn->m_mode != EQN_MODE_TEXT) { /* text in math */
2558 zcurr = Eqn_TranslateTEXTRUN(eqn, curr_node, &advance);
2559 while (advance > 1) {
2560 the_list = (MT_OBJLIST *) the_list->next;
2561 advance--;
2562 }
2563 }
2564 if (!advance)
2565 zcurr = Eqn_TranslateCHAR(eqn, charptr);
2566 }
2567 break;
2568
2569 case TMPL:{
2570 MT_TMPL *tmpl = (MT_TMPL *) curr_node->obj_ptr;
2571 if (tmpl)
2572 zcurr = Eqn_TranslateTMPL(eqn, tmpl);
2573 }
2574 break;
2575
2576 case PILE:{
2577 MT_PILE *pile = (MT_PILE *) curr_node->obj_ptr;
2578 if (pile)
2579 zcurr = Eqn_TranslatePILE(eqn, pile);
2580 }
2581 break;
2582
2583 case MATRIX:{
2584 MT_MATRIX *matrix = (MT_MATRIX *) curr_node->obj_ptr;
2585 if (matrix)
2586 zcurr = Eqn_TranslateMATRIX(eqn, matrix);
2587 }
2588 break;
2589
2590 case EMBELL:
2591 break;
2592
2593 case RULER:{
2594 MT_RULER *ruler = (MT_RULER *) curr_node->obj_ptr;
2595 if (ruler)
2596 zcurr = Eqn_TranslateRULER(eqn, ruler);
2597 }
2598 break;
2599
2600 case FONT:{
2601 MT_FONT *font = (MT_FONT *) curr_node->obj_ptr;
2602 if (font)
2603 zcurr = Eqn_TranslateFONT(eqn, font);
2604 }
2605 break;
2606
2607 case SIZE:
2608 case FULL:
2609 case SUB:
2610 case SUB2:
2611 case SYM:
2612 case SUBSYM:{
2613 MT_SIZE *size = (MT_SIZE *) curr_node->obj_ptr;
2614 if (size)
2615 zcurr = Eqn_TranslateSIZE(eqn, size);
2616 }
2617 break;
2618
2619 default:
2620 break;
2621 }
2622
2623 if (zcurr)
2624 rv = ToBuffer(zcurr, rv, &di, &lim);
2625
2626 } /* while ( the_list ) */
2627
2628 return rv;
2629 }
2630
Eqn_TranslateObjectList(MTEquation * eqn,FILE * outfile,int loglevel)2631 void Eqn_TranslateObjectList(MTEquation * eqn, FILE * outfile,
2632 int loglevel)
2633 {
2634 char *ztex;
2635
2636 eqn->out_file = outfile;
2637 eqn->log_level = loglevel;
2638
2639 if (eqn->log_level == 2)
2640 fputs("%Begin Equation\n", eqn->out_file);
2641
2642 if (DEBUG_TRANSLATION || g_input_file_type==TYPE_EQN) fprintf(stderr,"new equation\n");
2643
2644 ztex = Eqn_TranslateObjects(eqn, eqn->o_list);
2645
2646 if (eqn->m_latex_start && ztex && *ztex) {
2647 eqn->m_latex = ztex;
2648 if (!eqn->m_latex_end) setMathMode(eqn, EQN_MODE_TEXT);
2649 return;
2650 }
2651
2652 if (eqn->m_latex_start) free(eqn->m_latex_start);
2653 eqn->m_latex_start = NULL;
2654 if (eqn->m_latex) free(eqn->m_latex);
2655 eqn->m_latex = NULL;
2656 if (eqn->m_latex_end) free(eqn->m_latex_end);
2657 eqn->m_latex_end = NULL;
2658 }
2659
2660 /* [FUNCTIONS] */
2661 char *Profile_FUNCTIONS[] = {
2662 "Pr=\\Pr ",
2663 "arccos=\\arccos ",
2664 "arcsin=\\arcsin ",
2665 "arctan=\\arctan ",
2666 "arg=\\arg ",
2667 "cos=\\cos ",
2668 "cosh=\\cosh ",
2669 "cot=\\cot ",
2670 "coth=\\coth ",
2671 "csc=\\csc ",
2672 "deg=\\deg ",
2673 "det=\\det ",
2674 "dim=\\dim ",
2675 "exp=\\exp ",
2676 "gcd=\\gcd ",
2677 "hom=\\hom ",
2678 "inf=\\inf ",
2679 "ker=\\ker ",
2680 "lim=\\lim ",
2681 "liminf=\\liminf ",
2682 "limsup=\\limsup ",
2683 "ln=\\ln ",
2684 "log=\\log ",
2685 "max=\\max ",
2686 "min=\\min ",
2687 "sec=\\sec ",
2688 "sin=\\sin ",
2689 "sinh=\\sinh ",
2690 "sup=\\sup ",
2691 "tan=\\tan ",
2692 "tanh=\\tanh ",
2693 "mod=\\mathop{\\rm mod} ",
2694 "glb=\\mathop{\\rm glb} ",
2695 "lub=\\mathop{\\rm lub} ",
2696 "int=\\mathop{\\rm int} ",
2697 "Im=\\mathop{\\rm Im} ",
2698 "Re=\\mathop{\\rm Re} ",
2699 "var=\\mathop{\\rm var} ",
2700 "cov=\\mathop{\\rm cov} ",
2701 0
2702 };
2703
2704 /* [VARIABLES] */
2705 /* VARIABLE_NAME,MATH_VERSION,TEXT_VERSION */
2706 char *Profile_VARIABLES[] = {
2707 "STARTSUB=_{,\\Sb ",
2708 "ENDSUB=}, \\endSb ",
2709 "STARTSUP=^{,\\Sp ",
2710 "ENDSUP=}, \\endSp ",
2711 0
2712 };
2713
2714 /* [PILEtranslation] */
2715 char *Profile_PILEtranslation[] = {
2716 "MATHDEFAULT=MathForce,\\begin{array}{l}, \\\\,\\end{array}",
2717 "TEXTDEFAULT=TextOnly,\\begin{tabular}{l}, \\\\,\\end{tabular}",
2718 "L=,, \\ ,",
2719 "M=MathForce,\\begin{array}{l}, \\\\,\\end{array}",
2720 "X=TextForce,\\begin{texttest}, \\\\LINE_END,\\end{texttest}",
2721 "Y=MathForce,\\begin{mathtest}, \\\\LINE_END,\\end{mathtest}",
2722 0
2723 };
2724
2725
2726 /* typeface=attributes,do_lookup,use_codepoint */
2727 /* attributes --> 0=MA_NONE, 1=MA_FORCE_MATH, 2=MA_FORCE_TEXT, 3=2 translations */
2728 char *Profile_MT_CHARSET_ATTS[] = {
2729 "129=2,0,1", /* TEXT */
2730 "130=1,1,1", /* FUNCTION */
2731 "131=1,0,1", /* VARIABLE */
2732 "132=1,1,0", /* LCGREEK */
2733 "133=1,1,0", /* UCGREEK */
2734 "134=1,1,1", /* SYMBOL */
2735 "135=1,0,1", /* VECTOR */
2736 "136=1,0,1", /* NUMBER */
2737 "137=1,1,0",
2738 "138=1,1,0",
2739 "139=1,1,1", /* MTEXTRA */
2740 "140=1,1,0",
2741 "141=1,1,0",
2742 "142=1,1,0",
2743 "143=1,1,0",
2744 "144=1,1,0",
2745 "145=1,1,0",
2746 "146=1,1,0",
2747 "147=1,1,0",
2748 "148=1,1,0",
2749 "149=1,1,0",
2750 "150=1,1,0", /* EXPAND */
2751 "151=1,1,0", /* MARKER */
2752 "152=3,1,0", /* SPACE */
2753 "153=1,1,0",
2754 0
2755 };
2756
2757 /* [CHARTABLE] */
2758 char *Profile_CHARTABLE[] = {
2759 "130.91=\\lbrack ",
2760 "130.95=\\_ ", /* needed to properly escape '_' */
2761 "131.95=\\_ ",
2762 "132.74=\\vartheta ", /* encoding for lowercase greek */
2763 "132.86=\\varsigma ",
2764 "132.97=\\alpha ",
2765 "132.98=\\beta ",
2766 "132.99=\\chi ",
2767 "132.100=\\delta ",
2768 "132.101=\\epsilon ",
2769 "132.102=\\phi ",
2770 "132.103=\\gamma ",
2771 "132.104=\\eta ",
2772 "132.105=\\iota ",
2773 "132.106=\\varphi ",
2774 "132.107=\\kappa ",
2775 "132.108=\\lambda ",
2776 "132.109=\\mu ",
2777 "132.110=\\nu ",
2778 "132.111=\\o ",
2779 "132.112=\\pi ",
2780 "132.113=\\theta ",
2781 "132.114=\\rho ",
2782 "132.115=\\sigma ",
2783 "132.116=\\tau ",
2784 "132.117=\\upsilon ",
2785 "132.118=\\varpi ",
2786 "132.119=\\omega ",
2787 "132.120=\\xi ",
2788 "132.121=\\psi ",
2789 "132.122=\\zeta ",
2790 "132.182=\\partial ",
2791 "132.945=\\alpha ",
2792 "132.946=\\beta ",
2793 "132.967=\\chi ",
2794 "132.948=\\delta ",
2795 "132.949=\\epsilon ",
2796 "132.966=\\phi ",
2797 "132.947=\\gamma ",
2798 "132.951=\\eta ",
2799 "132.953=\\iota ",
2800 "132.981=\\varphi ",
2801 "132.954=\\kappa ",
2802 "132.955=\\lambda ",
2803 "132.956=\\mu ",
2804 "132.957=\\nu ",
2805 "132.959=\\o ",
2806 "132.960=\\pi ",
2807 "132.952=\\theta ",
2808 "132.961=\\rho ",
2809 "132.963=\\sigma ",
2810 "132.964=\\tau ",
2811 "132.965=\\upsilon ",
2812 "132.969=\\omega ",
2813 "132.958=\\xi ",
2814 "132.968=\\psi ",
2815 "132.950=\\zeta ",
2816 "132.977=\\vartheta ",
2817 "132.962=\\varsigma ",
2818 "132.982=\\varpi ",
2819 "133.65=A", /* encoding for upper case greek */
2820 "133.66=B",
2821 "133.67=X",
2822 "133.68=\\Delta ",
2823 "133.69=E",
2824 "133.70=\\Phi ",
2825 "133.71=\\Gamma ",
2826 "133.72=H",
2827 "133.73=I",
2828 "133.75=K",
2829 "133.76=\\Lambda ",
2830 "133.77=M",
2831 "133.78=N",
2832 "133.79=O",
2833 "133.80=\\Pi ",
2834 "133.81=\\Theta ",
2835 "133.82=P",
2836 "133.83=\\Sigma ",
2837 "133.84=T",
2838 "133.85=Y",
2839 "133.87=\\Omega ",
2840 "133.88=\\Xi ",
2841 "133.89=\\Psi ",
2842 "133.90=Z",
2843 "133.913=A",
2844 "133.914=B",
2845 "133.935=X",
2846 "133.916=\\Delta ",
2847 "133.917=E",
2848 "133.934=\\Phi ",
2849 "133.915=\\Gamma ",
2850 "133.919=H",
2851 "133.921=I",
2852 "133.922=K",
2853 "133.923=\\Lambda ",
2854 "133.924=M",
2855 "133.925=N",
2856 "133.927=O",
2857 "133.928=\\Pi ",
2858 "133.920=\\Theta ",
2859 "133.929=P",
2860 "133.931=\\Sigma ",
2861 "133.932=T",
2862 "133.933=Y",
2863 "133.937=\\Omega ",
2864 "133.926=\\Xi ",
2865 "133.936=\\Psi ",
2866 "133.918=Z",
2867 "134.34=\\forall ", /* symbol font encoding */
2868 "134.36=\\exists ",
2869 "134.39=\\ni ",
2870 "134.42=*",
2871 "134.43=+",
2872 "134.45=-",
2873 "134.61==",
2874 "134.64=\\cong ",
2875 "134.92=\\therefore ",
2876 "134.94=\\bot ",
2877 "134.97=\\alpha ",
2878 "134.98=\\beta ",
2879 "134.99=\\chi ",
2880 "134.100=\\delta ",
2881 "134.101=\\epsilon ",
2882 "134.102=\\phi ",
2883 "134.103=\\gamma ",
2884 "134.104=\\eta ",
2885 "134.105=\\iota ",
2886 "134.106=\\varphi ",
2887 "134.107=\\kappa ",
2888 "134.108=\\lambda ",
2889 "134.109=\\mu ",
2890 "134.110=\\nu ",
2891 "134.112=\\pi ",
2892 "134.113=\\theta ",
2893 "134.114=\\rho ",
2894 "134.115=\\sigma ",
2895 "134.116=\\tau ",
2896 "134.117=\\upsilon ",
2897 "134.118=\\varpi ",
2898 "134.119=\\omega ",
2899 "134.120=\\xi ",
2900 "134.121=\\psi ",
2901 "134.122=\\zeta ",
2902 "134.163=\\leq ",
2903 "134.165=\\infty ",
2904 "134.171=\\leftrightarrow ",
2905 "134.172=\\leftarrow ",
2906 "134.173=\\uparrow ",
2907 "134.174=\\rightarrow ",
2908 "134.175=\\downarrow ",
2909 "134.176=^\\circ ",
2910 "134.177=\\pm ",
2911 "134.179=\\geq ",
2912 "134.180=\\times ",
2913 "134.181=\\propto ",
2914 "134.182=\\partial ",
2915 "134.183=\\bullet ",
2916 "134.184=\\div ",
2917 "134.185=\\neq ",
2918 "134.186=\\equiv ",
2919 "134.187=\\approx ",
2920 "134.191=\\hookleftarrow ",
2921 "134.192=\\aleph ",
2922 "134.193=\\Im ",
2923 "134.194=\\Re ",
2924 "134.195=\\wp ",
2925 "134.196=\\otimes ",
2926 "134.197=\\oplus ",
2927 "134.198=\\emptyset ",
2928 "134.199=\\cap ",
2929 "134.200=\\cup ",
2930 "134.201=\\supset ",
2931 "134.202=\\supseteq ",
2932 "134.203=\\nsubset ",
2933 "134.204=\\subset ",
2934 "134.205=\\subseteq ",
2935 "134.206=\\in ",
2936 "134.207=\\notin ",
2937 "134.208=\\angle ",
2938 "134.209=\\nabla ",
2939 "134.213=\\prod ",
2940 "134.215=\\cdot ",
2941 /* "134.215=\\times ", */
2942 "134.216=\\neg ",
2943 "134.217=\\wedge ",
2944 "134.218=\\vee ",
2945 "134.219=\\Leftrightarrow ",
2946 "134.220=\\Leftarrow ",
2947 "134.221=\\Uparrow ",
2948 "134.222=\\Rightarrow ",
2949 "134.223=\\Downarrow ",
2950 "134.224=\\Diamond ",
2951 "134.225=\\langle ",
2952 "134.229=\\Sigma ",
2953 "134.241=\\rangle ",
2954 "134.242=\\smallint ",
2955 "134.247=\\div ",
2956 "134.8722=-",
2957 "134.8804=\\leq ",
2958 "134.8805=\\geq ",
2959 "134.8800=\\neq ",
2960 "134.8801=\\equiv ",
2961 "134.8776=\\approx ",
2962 "134.8773=\\cong ",
2963 "134.8733=\\propto ",
2964 "134.8727=\\ast ",
2965 "134.8901=\\cdot ",
2966 "134.8226=\\bullet ",
2967 "134.8855=\\otimes ",
2968 "134.8853=\\oplus ",
2969 "134.9001=\\langle ",
2970 "134.9002=\\rangle ",
2971 "134.8594=\\rightarrow ",
2972 "134.8592=\\leftarrow ",
2973 "134.8596=\\leftrightarrow ",
2974 "134.8593=\\uparrow ",
2975 "134.8595=\\downarrow ",
2976 "134.8658=\\Rightarrow ",
2977 "134.8656=\\Leftarrow ",
2978 "134.8660=\\Leftrightarrow ",
2979 "134.8657=\\Uparrow ",
2980 "134.8659=\\Downarrow ",
2981 "134.8629=\\hookleftarrow ",
2982 "134.8756=\\therefore ",
2983 "134.8717=\\backepsilon ",
2984 "134.8707=\\exists ",
2985 "134.8704=\\forall ",
2986 "134.172=\\neg ",
2987 "134.8743=\\wedge ",
2988 "134.8744=\\vee ",
2989 "134.8712=\\in ",
2990 "134.8713=\\notin ",
2991 "134.8746=\\cup ",
2992 "134.8745=\\cap ",
2993 "134.8834=\\subset ",
2994 "134.8835=\\supset ",
2995 "134.8838=\\subseteq ",
2996 "134.8839=\\supseteq ",
2997 "134.8836=\\not\\subset ",
2998 "134.8709=\\emptyset ",
2999 "134.8706=\\partial ",
3000 "134.8711=\\nabla ",
3001 "134.8465=\\Im ",
3002 "134.8476=\\Re ",
3003 "134.8501=\\aleph ",
3004 "134.8736=\\angle ",
3005 "134.8869=\\bot ",
3006 "134.8900=\\lozenge ",
3007 "134.8734=\\infty ",
3008 "134.8472=\\wp ",
3009 "134.8747=\\smallint",
3010 "134.8721=\\sum ",
3011 "134.8719=\\prod ",
3012 "139.58=\\sim ", /* MT Extra encoding */
3013 "139.59=\\simeq ",
3014 "139.60=\\vartriangleleft ",
3015 "139.61=\\ll ",
3016 "139.62=\\vartriangleright ",
3017 "139.63=\\gg ",
3018 "139.66=\\doteq ",
3019 "139.67=\\coprod ",
3020 "139.68=\\lambdabar ",
3021 "139.73=\\bigcap ",
3022 "139.75=\\ldots ",
3023 "139.76=\\cdots ",
3024 "139.77=\\vdots ",
3025 "139.78=\\ddots ",
3026 "139.79=\\ddots ",
3027 "139.81=\\because ",
3028 "139.85=\\bigcup ",
3029 "139.97=\\mapsto ",
3030 "139.98=\\updownarrow ",
3031 "139.99=\\Updownarrow ",
3032 "139.102=\\succ ",
3033 "139.104=\\hbar ",
3034 "139.108=\\ell ",
3035 "139.109=\\mp ",
3036 "139.111=\\circ ",
3037 "139.112=\\prec ",
3038 "139.8230=\\ldots ",
3039 "139.8943=\\cdots ",
3040 "139.8942=\\vdots ",
3041 "139.8944=\\ddots ",
3042 "139.8945=\\ddots ",
3043 "139.8826=\\prec ",
3044 "139.8827=\\succ ",
3045 "139.8882=\\vartriangleleft ",
3046 "139.8883=\\vartriangleright ",
3047 "139.8723=\\mp ",
3048 "139.8728=\\circ ",
3049 "139.8614=\\longmapsto ",
3050 "139.8597=\\updownarrow ",
3051 "139.8661=\\Updownarrow ",
3052 "139.4746=\\bigcup ",
3053 "139.4745=\\bigcap ",
3054 "139.8757=\\because ",
3055 "139.8467=\\ell ",
3056 "139.8463=\\hbar ",
3057 "139.411=\\lambdabar ",
3058 "139.8720=\\coprod ",
3059 "151.60160m={}",
3060 "151.60160t={}",
3061 "152.1m={}",
3062 "152.1t={}",
3063 "152.8m=\\/",
3064 "152.8t=\\/",
3065 "152.2m=\\,",
3066 "152.2t=\\thinspace ",
3067 "152.4m=\\;",
3068 "152.4t=\\ ",
3069 "152.5m=\\quad ",
3070 "152.5t=\\quad ",
3071 "152.60161m=\\/",
3072 "152.60161t=\\/",
3073 "152.61168m=@,",
3074 "152.61168t=",
3075 "152.60162m=\\,",
3076 "152.60162t=\\thinspace ",
3077 "152.60164m=\\;",
3078 "152.60164t=\\ ",
3079 "152.60165m=\\quad ",
3080 "152.60165t=\\quad ",
3081 "152.61186m=\\, ",
3082 "152.61186t=\\thinspace ",
3083 0
3084 };
3085
3086 /* [TEMPLATES] */
3087 char *Profile_TEMPLATES[] = {
3088 "0.0=fence: angle-both,\\left\\langle #1[M]\\right\\rangle ",
3089 "0.1=fence: angle-left only,\\left\\langle #1[M]\\right. ",
3090 "0.2=fence: angle-right only,\\left. #1[M]\\right\\rangle ",
3091 "1.0=fence: paren-both,\\left( #1[M]\\right) ",
3092 "1.1=fence: paren-left only,\\left( #1[M]\\right. ",
3093 "1.2=fence: paren-right only,\\left. #1[M]\\right) ",
3094 "2.0=fence: brace-both,\\left\\{ #1[M]\\right\\} ",
3095 "2.1=fence: brace-left only,\\left\\{ #1[M]\\right. ",
3096 "2.2=fence: brace-right only,\\left. #1[M]\\right\\} ",
3097 "3.0=fence: brack-both,\\left[ #1[M]\\right] ",
3098 "3.1=fence: brack-left only,\\lef]t[ #1[M]\\right. ",
3099 "3.2=fence: brack-right only,\\left. #1[M]\\right] ",
3100 "4.0=fence: bar-both,\\left| #1[M]\\right| ",
3101 "4.1=fence: bar-left only,\\left| #1[M]\\right. ",
3102 "4.2=fence: bar-right only,\\left. #1[M]\\right| ",
3103 "5.0=fence: dbar-both,\\left\\| #1[M]\\right\\| ",
3104 "5.1=fence: dbar-left only,\\left\\| #1[M]\\right. ",
3105 "5.2=fence: dbar-right only,\\left. #1[M]\\right\\| ",
3106 "6.0=fence: floor,\\left\\lfloor #1[M]\\right\\rfloor ",
3107 "7.0=fence: ceiling,\\left\\lceil #1[M]\\right\\rceil ",
3108 "8.0=fence: LBLB,\\left[ #1[M]\\right[ ",
3109 "9.0=fence: RBRB,\\left] #1[M]\\right] ",
3110 "10.0=fence: RBLB,\\left] #1[M]\\right[ ",
3111 "11.0=fence: LBRP,\\left[ #1[M]\\right) ",
3112 "12.0=fence: LPRB,\\left( #1[M]\\right] ",
3113 "13.0=root: sqroot,\\sqrt{#1[M]} ",
3114 "13.1=root: nthroot,\\sqrt[#2[M]]{#1[M]} ",
3115 "14.0=fract: ffract,\\frac{#1[M]}{#2[M]} ",
3116 "14.1=fract: pfract,\\frac{#1[M]}{#2[M]} ",
3117 "15.0=script: super,#1[L][STARTSUP][ENDSUP] ",
3118 "15.1=script: sub,#1[L][STARTSUB][ENDSUB] ",
3119 "15.2=script: subsup,#1[L][STARTSUB][ENDSUB]#2[L][STARTSUP][ENDSUP] ",
3120 "16.0=ubar: subar,\\underline{#1[M]} ",
3121 "16.1=ubar: dubar,\\underline{\\underline{#1[M]}} ",
3122 "17.0=obar: sobar,\\overline{#1[M]} ",
3123 "17.1=obar: dobar,\\overline{\\overline{#1[M]}} ",
3124 "18.0=larrow: box on top,\\stackrel{#1[M]}{\\longleftarrow} ",
3125 "18.1=larrow: box below ,\\stackunder{#1[M]}{\\longleftarrow} ",
3126 "19.0=rarrow: box on top,\\stackrel{#1[M]}{\\longrightarrow} ",
3127 "19.1=rarrow: box below ,\\stackunder{#1[M]}{\\longrightarrow} ",
3128 "20.0=barrow: box on top,\\stackrel{#1[M]}{\\longleftrightarrow} ",
3129 "20.1=barrow: box below ,\\stackunder{#1[M]}{\\longleftrightarrow} ",
3130 "21.0=integrals: single - no limits,\\int #1[M] ",
3131 "21.1=integrals: single - lower only,\\int\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3132 "21.2=integrals: single - both,\\int\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3133 "21.3=integrals: contour - no limits,\\oint #1[M] ",
3134 "21.4=integrals: contour - lower only,\\oint\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3135 "22.0=integrals: double - no limits ,\\iint #1[M] ",
3136 "22.1=integrals: double - lower only,\\iint\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3137 "22.2=integrals: area - no limits ,\\iint #1[M] ",
3138 "22.3=integrals: area - lower only,\\iint\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3139 "23.0=integrals: triple - no limits ,\\iiint #1[M] ",
3140 "23.1=integrals: triple - lower only,\\iiint\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3141 "23.2=integrals: volume - no limits ,\\iiint #1[M] ",
3142 "23.3=integrals: volume - lower only,\\iiint\\nolimits#2[L][STARTSUB][ENDSUB] #1[M] ",
3143 "24.0=integrals: single - sum style - both,\\int\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3144 "24.1=integrals: single - sum style - lower only,\\int\\limits#2[L][STARTSUB][ENDSUB]#1[M] ",
3145 "24.2=integrals: contour - sum style - lower only,\\oint\\limits#2[L][STARTSUB][ENDSUB] #1[M] ",
3146 "25.0=integrals: area - sum style - lower only,\\iint\\limits#2[L][STARTSUB][ENDSUB] #1[M] ",
3147 "25.1=integrals: double - sum style - lower only,\\iint\\limits#2[L][STARTSUB][ENDSUB] #1[M] ",
3148 "26.0=integrals: volume - sum style - lower only,\\iiint\\limits#2[L][STARTSUB][ENDSUB] #1[M] ",
3149 "26.1=integrals: triple - sum style - lower only,\\iiint\\limits#2[L][STARTSUB][ENDSUB] #1[M] ",
3150 "27.0=horizontal braces: upper,\\stackrel{#2[M]}{\\overbrace{#1[M]}} ",
3151 "28.0=horizontal braces: lower,\\stackunder{#2[M]}{\\underbrace{#1[M]}} ",
3152 "29.0=sum: limits top/bottom - lower only,\\sum\\limits#2[L][STARTSUB][ENDSUB]#1[M] ",
3153 "29.1=sum: limits top/bottom - both,\\sum\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3154 "29.2=sum: no limits,\\sum #1[M] ",
3155 "30.0=sum: limits right - lower only,\\sum\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3156 "30.1=sum: limits right - both,\\sum\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3157 "31.0=product: limits top/bottom - lower only,\\dprod\\limits#2[L][STARTSUB][ENDSUB]#1[M] ",
3158 "31.1=product: limits top/bottom - both,\\dprod\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3159 "31.2=product: no limits,\\dprod #1[M] ",
3160 "32.0=product: limits right - lower only,\\dprod\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3161 "32.1=product: limits right - both,\\dprod\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3162 "33.0=coproduct: limits top/bottom - lower only,\\dcoprod\\limits#2[L][STARTSUB][ENDSUB]#1[M] ",
3163 "33.1=coproduct: limits top/bottom - both,\\dcoprod\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3164 "33.2=coproduct: no limits,\\dcoprod #1[M] ",
3165 "34.0=coproduct: limits right - lower only,\\dcoprod\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3166 "34.1=coproduct: limits right - both,\\dcoprod\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3167 "35.0=union: limits top/bottom - lower only,\\dbigcup\\limits#2[L][STARTSUB][ENDSUB]#1[M] ",
3168 "35.1=union: limits top/bottom - both,\\dbigcup\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3169 "35.2=union: no limits,\\dbigcup #1[M] ",
3170 "36.0=union: limits right - lower only,\\dbigcup\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3171 "36.1=union: limits right - both,\\dbigcup\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3172 "37.0=intersection: limits top/bottom - lower only,\\dbigcap\\limits#2[L][STARTSUB][ENDSUB]#1[M] ",
3173 "37.1=intersection: limits top/bottom - both,\\dbigcap\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3174 "37.2=intersection: no limits,\\dbigcap #1[M] ",
3175 "38.0=intersection: limits right - lower only,\\dbigcap\\nolimits#2[L][STARTSUB][ENDSUB]#1[M] ",
3176 "38.1=intersection: limits right - both,\\dbigcap\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3177 "39.0=limit: upper,#1 #2[L][STARTSUP][ENDSUP] ",
3178 "39.1=limit: lower,#1 #2[L][STARTSUB][ENDSUB] ",
3179 "39.2=limit: both,#1 #2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP] ",
3180 "40.0=long divisionW,",
3181 "40.1=long divisionWO,",
3182 "41.0=slash fraction: normal,\\frac{#1[M]}{#2[M]} ",
3183 "41.1=slash fraction: baseline,#1[M]/#2[M] ",
3184 "41.2=slash fraction: subscript-sized,\\frac{#1[M]}{#2[M]} ",
3185 "42.0=INTOP: upper,",
3186 "42.1=INTOP: lower,",
3187 "42.2=INTOP: both,",
3188 "43.0=SUMOP: upper,",
3189 "43.1=SUMOP: lower,",
3190 "43.2=SUMOP: both,",
3191 "44.0=leadingSUPER,",
3192 "44.1=leadingSUB,",
3193 "44.2=leadingSUBSUP,",
3194 "45.0=Dirac: both,\\left\\langle #1[M]\\right.\\left| #2[M]\\right\\rangle ",
3195 "45.1=Dirac: left,\\left\\langle #1[M]\\right| ",
3196 "45.2=Dirac: right,\\left| #1[M]\\right\\rangle ",
3197 "46.0=under arrow: left,\\underleftarrow{#1[M]} ",
3198 "46.1=under arrow: right,\\underrightarrow{#1[M]} ",
3199 "46.2=under arrow: both,\\underleftrightarrow{#1[M]} ",
3200 "47.0=over arrow: left,\\overleftarrow{#1[M]} ",
3201 "47.1=over arrow: right,\\overrightarrow{#1[M]} ",
3202 "47.2=over arrow: both,\\overleftrightarrow{#1[M]} ",
3203 "TextInMath=\\text{#1} ",
3204 0
3205 };
3206
3207 /* [TEMPLATES] */
3208 char *Profile_TEMPLATES_5[] = {
3209 "0.1=fence: angle-left only,\\left\\langle #1[M]\\right. ",
3210 "0.2=fence: angle-right only,\\left. #1[M]\\right\\rangle ",
3211 "0.3=fence: angle-both,\\left\\langle #1[M]\\right\\rangle ",
3212 "1.1=fence: paren-left only,\\left( #1[M]\\right. ",
3213 "1.2=fence: paren-right only,\\left. #1[M]\\right) ",
3214 "1.3=fence: paren-both,\\left( #1[M]\\right) ",
3215 "2.1=fence: brace-left only,\\left\\{ #1[M]\\right. ",
3216 "2.2=fence: brace-right only,\\left. #1[M]\\right\\} ",
3217 "2.3=fence: brace-both,\\left\\{ #1[M]\\right\\} ",
3218 "3.1=fence: brack-left only,\\lef]t[ #1[M]\\right. ",
3219 "3.2=fence: brack-right only,\\left. #1[M]\\right] ",
3220 "3.3=fence: brack-both,\\left[ #1[M]\\right] ",
3221 "4.1=fence: bar-left only,\\left| #1[M]\\right. ",
3222 "4.2=fence: bar-right only,\\left. #1[M]\\right| ",
3223 "4.3=fence: bar-both,\\left| #1[M]\\right| ",
3224 "5.1=fence: dbar-left only,\\left\\| #1[M]\\right. ",
3225 "5.2=fence: dbar-right only,\\left. #1[M]\\right\\| ",
3226 "5.3=fence: dbar-both,\\left\\| #1[M]\\right\\| ",
3227 "6.1=fence: floor,\\left\\lfloor #1[M]\\right. ",
3228 "6.2=fence: floor,\\left. #1[M]\\right\\rfloor ",
3229 "6.3=fence: floor,\\left\\lfloor #1[M]\\right\\rfloor ",
3230 "7.1=fence: ceiling,\\left\\lceil #1[M]\\right. ",
3231 "7.2=fence: ceiling,\\left. #1[M]\\right\\rceil ",
3232 "7.3=fence: ceiling,\\left\\lceil #1[M]\\right\\rceil ",
3233 "8.0=fence: LBLB,\\left[ #1[M]\\right[ ",
3234 "9.0=fence: LPLP,\\left( #1[M]\\right( ",
3235 "9.1=fence: RPLP,\\left) #1[M]\\right( ",
3236 "9.2=fence: LBLP,\\left[ #1[M]\\right( ",
3237 "9.3=fence: RBLP,\\left] #1[M]\\right( ",
3238 "9.16=fence: LPRP,\\left( #1[M]\\right) ",
3239 "9.17=fence: RPRP,\\left) #1[M]\\right) ",
3240 "9.18=fence: LBRP,\\left[ #1[M]\\right) ",
3241 "9.19=fence: RBRP,\\left] #1[M]\\right) ",
3242 "9.32=fence: LPLB,\\left( #1[M]\\right[ ",
3243 "9.33=fence: RPLB,\\left) #1[M]\\right[ ",
3244 "9.34=fence: LBLB,\\left[ #1[M]\\right[ ",
3245 "9.35=fence: RBLB,\\left] #1[M]\\right[ ",
3246 "9.48=fence: LPRB,\\left( #1[M]\\right] ",
3247 "9.49=fence: RPRB,\\left) #1[M]\\right] ",
3248 "9.50=fence: LBRB,\\left[ #1[M]\\right] ",
3249 "9.51=fence: RBRB,\\left] #1[M]\\right] ",
3250 "10.0=root: sqroot,\\sqrt{#1[M]} ",
3251 "10.1=root: nthroot,\\sqrt[#2[M]]{#1[M]} ",
3252 "11.0=fract: tmfract,\\frac{#1[M]}{#2[M]} ",
3253 "11.1=fract: smfract,\\frac{#1[M]}{#2[M]} ",
3254 "11.2=fract: slfract,{#1[M]}/{#2[M]} ",
3255 "11.3=fract: slfract,{#1[M]}/{#2[M]} ",
3256 "11.4=fract: slfract,{#1[M]}/{#2[M]} ",
3257 "11.5=fract: smfract,\\frac{#1[M]}{#2[M]} ",
3258 "11.6=fract: slfract,{#1[M]}/{#2[M]} ",
3259 "11.7=fract: slfract,{#1[M]}/{#2[M]} ",
3260 "12.0=ubar: subar,\\underline{#1[M]} ",
3261 "12.1=ubar: dubar,\\underline{\\underline{#1[M]}} ",
3262 "13.0=obar: sobar,\\overline{#1[M]} ",
3263 "13.1=obar: dobar,\\overline{\\overline{#1[M]}} ",
3264 "14.0=larrow: box on top,\\stackrel{#1[M]}{\\longleftarrow} ",
3265 "14.1=larrow: box below ,\\stackunder{#1[M]}{\\longleftarrow} ",
3266 "14.0=rarrow: box on top,\\stackrel{#1[M]}{\\longrightarrow} ",
3267 "14.1=rarrow: box below ,\\stackunder{#1[M]}{\\longrightarrow} ",
3268 "14.0=barrow: box on top,\\stackrel{#1[M]}{\\longleftrightarrow} ",
3269 "14.1=barrow: box below ,\\stackunder{#1[M]}{\\longleftrightarrow} ",
3270 "15.0=integrals: single - no limits,\\int #1[M] ",
3271 "15.1=integrals: single - both,\\int\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3272 "15.2=integrals: double - both,\\iint\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3273 "15.3=integrals: triple - both,\\iiint\\nolimits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3274 "15.4=integrals: contour - no limits,\\oint #1[M] ",
3275 "15.8=integrals: contour - no limits,\\oint #1[M] ",
3276 "15.12=integrals: contour - no limits,\\oint #1[M] ",
3277 "16.0=sum: limits top/bottom - both,\\sum\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3278 "17.0=product: limits top/bottom - both,\\dprod\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3279 "18.0=coproduct: limits top/bottom - both,\\dcoprod\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3280 "19.0=union: limits top/bottom - both,\\dbigcup\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3281 "20.0=intersection: limits top/bottom - both,\\dbigcap\\limits#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3282 "21.0=integrals: single - both,\\int#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3283 "22.0=sum: single - both,\\sum#2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP]#1[M] ",
3284 "23.0=limit: both,#1 #2[L][STARTSUB][ENDSUB]#3[L][STARTSUP][ENDSUP] ",
3285 "24.0=horizontal brace: lower,\\stackunder{#2[M]}{\\underbrace{#1[M]}} ",
3286 "24.1=horizontal brace: upper,\\stackrel{#2[M]}{\\overbrace{#1[M]}} ",
3287 "25.0=horizontal brace: lower,\\stackunder{#2[M]}{\\underbrace{#1[M]}} ",
3288 "25.1=horizontal brace: upper,\\stackrel{#2[M]}{\\overbrace{#1[M]}} ",
3289 "25.0=hbracket,",
3290 "26.0=limi",
3291 "27.0=script: sub,#1[L][STARTSUB][ENDSUB] ",
3292 "27.1=script: sub,#1[L][STARTSUB][ENDSUB] ",
3293 "28.0=script: super,#2[L][STARTSUP][ENDSUP] ",
3294 "28.1=script: super,#2[L][STARTSUP][ENDSUP] ",
3295 "29.0=script: subsup,#1[L][STARTSUB][ENDSUB]#2[L][STARTSUP][ENDSUP] ",
3296 "30.0=limi",
3297 "31.0=limi",
3298 "32.0=limi",
3299 "33.0=limi",
3300 "34.0=limi",
3301 "35.0=limi",
3302 "36.0=limi",
3303 "37.0=limi",
3304 "TextInMath=\\text{#1} ",
3305 0
3306 };
3307
3308 /* [EMBELLS] */
3309 /* ;format is "math template,text template" (different from all the above) */
3310 char *Template_EMBELLS[] = {
3311 "",
3312 "",
3313 /* embDOT */ "\\dot{%1} ,\\.%1 ",
3314 /* embDDOT */ "\\ddot{%1} ,\\\"%1 ",
3315 /* embTDOT */ "\\dddot{%1} ,%1 ",
3316 /* embPRIME */ "%1' ,%1 ",
3317 /* embDPRIME */ "%1'' ,%1 ",
3318 /* embBPRIME */ "\\backprime %1 , %1",
3319 /* embTILDE */ "\\tilde{%1} ,\\~%1 ",
3320 /* embHAT */ "\\hat{%1} ,\\^%1 ",
3321 /* embNOT */ "\\not %1 ,\\NEG %1 ",
3322 /* embRARROW */ "\\vec{%1} ,%1 ",
3323 /* embLARROW */ "\\overleftarrow1{%1} ,%1 ",
3324 /* embBARROW */ "\\overleftrightarrow{%1} ,%1 ",
3325 /* embR1ARROW */ "\\overrightarrow{%1} ,%1 ",
3326 /* embL1ARROW */ "\\overleftarrow{%1} ,%1 ",
3327 /* embMBAR */ "\\underline{%1} ,%1 ",
3328 /* embOBAR */ "\\bar{%1} ,\\=%1 ",
3329 /* embTPRIME */ "%1''' ,",
3330 /* embFROWN */ "\\widehat{%1} ,%1 ",
3331 /* embSMILE */ "\\breve{%1} ,%1 ",
3332 /* embX_BARS */ "{%1} ,%1 ",
3333 /* embUP_BAR */ "{%1} ,%1 ",
3334 /* embDOWN_BAR */ "{%1} ,%1 ",
3335 /* emb4DOT */ "{%1} ,%1 ",
3336 /* embU_1DOT */ "\\d{%1} ,\\d{%1} ",
3337 /* embU_2DOT */ "{%1} ,%1 ",
3338 /* embU_3DOT */ "{%1} ,%1 ",
3339 /* embU_4DOT */ "{%1} ,%1 ",
3340 /* embU_BAR */ "{%1} ,%1 ",
3341 /* embU_TILDE */ "{%1} ,%1 ",
3342 /* embU_FROWN */ "{%1} ,%1 ",
3343 /* embU_SMILE */ "{%1} ,%1 ",
3344 /* embU_RARROW */ "{%1} ,%1 ",
3345 /* embU_LARROW */ "{%1} ,%1 ",
3346 /* embU_BARROW */ "{%1} ,%1 ",
3347 /* embU_R1ARROW */ "{%1} ,%1 ",
3348 /* embU_L1ARROW */ "{%1} ,%1 ",
3349 0
3350 };
3351