/itexToMML

To download this project, use:
bzr branch http://golem.ph.utexas.edu/~distler/code/itexToMML/
1 by Jacques Distler
Initial commit.
1
/*             itex2MML 1.1.8
2
 *   itex2MML.y last modified 12/24/2006
3
 */
4
5
%{
6
#include <stdio.h>
7
#include <string.h>
8
#include <stdlib.h>
9
10
#include "itex2MML.h"
11
12
#define YYSTYPE char *
13
#define YYPARSE_PARAM_TYPE char **
14
#define YYPARSE_PARAM ret_str
15
16
#define yytext itex2MML_yytext
17
18
 extern int yylex ();
19
20
 extern char * yytext;
21
22
 static void itex2MML_default_error (const char * msg)
23
   {
24
     if (msg)
25
       fprintf(stderr, "Line: %d Error: %s\n", itex2MML_lineno, msg);
26
   }
27
28
 void (*itex2MML_error) (const char * msg) = itex2MML_default_error;
29
30
 static void yyerror (char * s)
31
   {
32
     char * msg = itex2MML_copy3 (s, " at token ", yytext);
33
     if (itex2MML_error)
34
       (*itex2MML_error) (msg);
35
     itex2MML_free_string (msg);
36
   }
37
38
 /* Note: If length is 0, then buffer is treated like a string; otherwise only length bytes are written.
39
  */
40
 static void itex2MML_default_write (const char * buffer, unsigned long length)
41
   {
42
     if (buffer)
43
       {
44
	 if (length)
45
	   fwrite (buffer, 1, length, stdout);
46
	 else
47
	   fputs (buffer, stdout);
48
       }
49
   }
50
51
 static void itex2MML_default_write_mathml (const char * mathml)
52
   {
53
     if (itex2MML_write)
54
       (*itex2MML_write) (mathml, 0);
55
   }
56
57
#ifdef itex2MML_CAPTURE
58
    static char * itex2MML_output_string = "" ;
59
60
    const char * itex2MML_output ()
61
    {
62
        char * copy = (char *) malloc(strlen(itex2MML_output_string) +1);
63
        if (copy)
64
          {
65
           if (itex2MML_output_string)
66
             {
67
               strcpy(copy, itex2MML_output_string);
68
               if (itex2MML_output_string != "")
69
                   free(itex2MML_output_string);
70
             }
71
           else
72
             copy[0] = 0;
73
          }
74
        itex2MML_output_string = "";
75
        return copy;
76
    }
77
78
 static void itex2MML_capture (const char * buffer, unsigned long length)
79
    {
80
     if (buffer)
81
       {
82
         if (length)
83
           {
84
              unsigned long first_length = itex2MML_output_string ? strlen(itex2MML_output_string) : 0;
85
              char * copy  = (char *) malloc(first_length + length + 1);
86
              if (copy)
87
                {
88
                  if (itex2MML_output_string)
89
                    {
90
                       strcpy(copy, itex2MML_output_string);
91
                       if (itex2MML_output_string != "")
92
                          free(itex2MML_output_string);
93
                    }
94
                  else
95
                     copy[0] = 0;
96
                  strncat(copy, buffer, length);
97
                 }
98
              itex2MML_output_string = copy;
99
            }
100
         else
101
            {
102
              char * copy = itex2MML_copy2(itex2MML_output_string, buffer);
103
              if (itex2MML_output_string != "")
104
                 free(itex2MML_output_string);
105
              itex2MML_output_string = copy;
106
            }
107
        }
108
    }
109
110
    static void itex2MML_capture_mathml (const char * buffer)
111
    {
112
       char * temp = itex2MML_copy2(itex2MML_output_string, buffer);
113
       if (itex2MML_output_string != "")
114
         free(itex2MML_output_string);
115
       itex2MML_output_string = temp;
116
    }
117
    void (*itex2MML_write) (const char * buffer, unsigned long length) = itex2MML_capture;
118
    void (*itex2MML_write_mathml) (const char * mathml) = itex2MML_capture_mathml;
119
#else
120
    void (*itex2MML_write) (const char * buffer, unsigned long length) = itex2MML_default_write;
121
    void (*itex2MML_write_mathml) (const char * mathml) = itex2MML_default_write_mathml;
122
#endif 
123
124
 char * itex2MML_empty_string = "";
125
126
 /* Create a copy of a string, adding space for extra chars
127
  */
128
 char * itex2MML_copy_string_extra (const char * str, unsigned extra)
129
   {
130
     char * copy = (char *) malloc(extra + (str ? strlen (str) : 0) + 1);
131
     if (copy)
132
       {
133
	 if (str)
134
	   strcpy(copy, str);
135
	 else
136
	   copy[0] = 0;
137
       }
138
     return copy ? copy : itex2MML_empty_string;
139
   }
140
141
 /* Create a copy of a string, appending two strings
142
  */
143
 char * itex2MML_copy3 (const char * first, const char * second, const char * third)
144
   {
145
     int  first_length =  first ? strlen( first) : 0;
146
     int second_length = second ? strlen(second) : 0;
147
     int  third_length =  third ? strlen( third) : 0;
148
149
     char * copy = (char *) malloc(first_length + second_length + third_length + 1);
150
151
     if (copy)
152
       {
153
	 if (first)
154
	   strcpy(copy, first);
155
	 else
156
	   copy[0] = 0;
157
158
	 if (second) strcat(copy, second);
159
	 if ( third) strcat(copy,  third);
160
       }
161
     return copy ? copy : itex2MML_empty_string;
162
   }
163
164
 /* Create a copy of a string, appending a second string
165
  */
166
 char * itex2MML_copy2 (const char * first, const char * second)
167
   {
168
     return itex2MML_copy3(first, second, 0);
169
   }
170
171
 /* Create a copy of a string
172
  */
173
 char * itex2MML_copy_string (const char * str)
174
   {
175
     return itex2MML_copy3(str, 0, 0);
176
   }
177
178
 /* Create a copy of a string, escaping unsafe characters for XML
179
  */
180
 char * itex2MML_copy_escaped (const char * str)
181
   {
182
     unsigned long length = 0;
183
184
     const char * ptr1 = str;
185
186
     char * ptr2 = 0;
187
     char * copy = 0;
188
189
     if ( str == 0) return itex2MML_empty_string;
190
     if (*str == 0) return itex2MML_empty_string;
191
192
     while (*ptr1)
193
       {
194
	 switch (*ptr1)
195
	   {
196
	   case '<':  /* &lt;   */
197
	   case '>':  /* &gt;   */
198
	     length += 4;
199
	     break;
200
	   case '&':  /* &amp;  */
201
	     length += 5;
202
	     break;
203
	   case '\'': /* &apos; */
204
	   case '"':  /* &quot; */
205
	   case '-':  /* &#x2d; */
206
	     length += 6;
207
	     break;
208
	   default:
209
	     length += 1;
210
	     break;
211
	   }
212
	 ++ptr1;
213
       }
214
215
     copy = (char *) malloc (length + 1);
216
217
     if (copy)
218
       {
219
	 ptr1 = str;
220
	 ptr2 = copy;
221
222
	 while (*ptr1)
223
	   {
224
	     switch (*ptr1)
225
	       {
226
	       case '<':
227
		 strcpy (ptr2, "&lt;");
228
		 ptr2 += 4;
229
		 break;
230
	       case '>':
231
		 strcpy (ptr2, "&gt;");
232
		 ptr2 += 4;
233
		 break;
234
	       case '&':  /* &amp;  */
235
		 strcpy (ptr2, "&amp;");
236
		 ptr2 += 5;
237
		 break;
238
	       case '\'': /* &apos; */
239
		 strcpy (ptr2, "&apos;");
240
		 ptr2 += 6;
241
		 break;
242
	       case '"':  /* &quot; */
243
		 strcpy (ptr2, "&quot;");
244
		 ptr2 += 6;
245
		 break;
246
	       case '-':  /* &#x2d; */
247
		 strcpy (ptr2, "&#x2d;");
248
		 ptr2 += 6;
249
		 break;
250
	       default:
251
		 *ptr2++ = *ptr1;
252
		 break;
253
	       }
254
	     ++ptr1;
255
	   }
256
	 *ptr2 = 0;
257
       }
258
     return copy ? copy : itex2MML_empty_string;
259
   }
260
261
 void itex2MML_free_string (char * str)
262
   {
263
     if (str && str != itex2MML_empty_string)
264
       free(str);
265
   }
266
267
%}
268
269
%left TEXOVER
270
%token CHAR STARTMATH STARTDMATH ENDMATH MI MIB MN MO SUP SUB MROWOPEN MROWCLOSE LEFT RIGHT BIG BBIG BIGG BBIGG BIGL BBIGL BIGGL BBIGGL FRAC TFRAC MATHOP MOP MOL MOF PERIODDELIM OTHERDELIM LEFTDELIM RIGHTDELIM MOS MOB SQRT ROOT BINOM UNDER OVER OVERBRACE UNDERBRACE UNDEROVER TENSOR MULTI ARRAY COLSEP ROWSEP ARRAYOPTS COLLAYOUT COLALIGN ROWALIGN ALIGN EQROWS EQCOLS ROWLINES COLLINES FRAME PADDING ATTRLIST ITALICS BOLD RM BB ST END BBLOWERCHAR BBUPPERCHAR CALCHAR FRAKCHAR CAL FRAK ROWOPTS TEXTSIZE SCSIZE SCSCSIZE DISPLAY TEXTSTY TEXTBOX TEXTSTRING CELLOPTS ROWSPAN COLSPAN THINSPACE MEDSPACE THICKSPACE QUAD QQUAD NEGSPACE PHANTOM HREF UNKNOWNCHAR EMPTYMROW STATLINE TOGGLE FGHIGHLIGHT BGHIGHLIGHT SPACE INTONE INTTWO INTTHREE BAR WIDEBAR VEC WIDEVEC HAT WIDEHAT CHECK WIDECHECK TILDE WIDETILDE DOT DDOT UNARYMINUS UNARYPLUS BEGINENV ENDENV MATRIX PMATRIX BMATRIX BBMATRIX VMATRIX VVMATRIX SMALLMATRIX CASES ALIGNED SUBSTACK PMOD RMCHAR COLOR BGCOLOR
271
272
%%
273
274
doc:  xmlmmlTermList {/* all processing done in body*/};
275
276
xmlmmlTermList:
277
{/* nothing - do nothing*/}
278
| char {/* proc done in body*/}
279
| expression {/* all proc. in body*/}
280
| xmlmmlTermList char {/* all proc. in body*/}
281
| xmlmmlTermList expression {/* all proc. in body*/};
282
283
char: CHAR {printf("%s", $1);};
284
285
expression: STARTMATH ENDMATH {/* empty math group - ignore*/}
286
| STARTDMATH ENDMATH {/* ditto */}
287
| STARTMATH compoundTermList ENDMATH {
288
  char ** r = (char **) ret_str;
289
  char * s = itex2MML_copy3("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'>", $2, "</math>");
290
  itex2MML_free_string($2);
291
  if (r) {
292
    (*r) = (s == itex2MML_empty_string) ? 0 : s;
293
  }
294
  else {
295
    if (itex2MML_write_mathml)
296
      (*itex2MML_write_mathml) (s);
297
    itex2MML_free_string(s);
298
  }
299
}
300
| STARTDMATH compoundTermList ENDMATH {
301
  char ** r = (char **) ret_str;
302
  char * s = itex2MML_copy3("<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>", $2, "</math>");
303
  itex2MML_free_string($2);
304
  if (r) {
305
    (*r) = (s == itex2MML_empty_string) ? 0 : s;
306
  }
307
  else {
308
    if (itex2MML_write_mathml)
309
      (*itex2MML_write_mathml) (s);
310
    itex2MML_free_string(s);
311
  }
312
};
313
314
compoundTermList: compoundTerm {
315
  $$ = itex2MML_copy_string($1);
316
  itex2MML_free_string($1);
317
}
318
| compoundTermList compoundTerm {
319
  $$ = itex2MML_copy2($1, $2);
320
  itex2MML_free_string($1);
321
  itex2MML_free_string($2);
322
};
323
324
compoundTerm: mob SUB closedTerm SUP closedTerm {
325
  if (itex2MML_displaymode == 1) {
326
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
327
    char * s2 = itex2MML_copy3($3, " ", $5);
328
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
329
    itex2MML_free_string(s1);
330
    itex2MML_free_string(s2);
331
  }
332
  else {
333
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
334
    char * s2 = itex2MML_copy3($3, " ", $5);
335
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
336
    itex2MML_free_string(s1);
337
    itex2MML_free_string(s2);
338
  }
339
  itex2MML_free_string($1);
340
  itex2MML_free_string($3);
341
  itex2MML_free_string($5);
342
}
343
| mob SUB closedTerm {
344
  if (itex2MML_displaymode == 1) {
345
    char * s1 = itex2MML_copy3("<munder>", $1, " ");
346
    $$ = itex2MML_copy3(s1, $3, "</munder>");
347
    itex2MML_free_string(s1);
348
  }
349
  else {
350
    char * s1 = itex2MML_copy3("<msub>", $1, " ");
351
    $$ = itex2MML_copy3(s1, $3, "</msub>");
352
    itex2MML_free_string(s1);
353
  }
354
  itex2MML_free_string($1);
355
  itex2MML_free_string($3);
356
}
357
| mob SUP closedTerm SUB closedTerm {
358
  if (itex2MML_displaymode == 1) {
359
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
360
    char * s2 = itex2MML_copy3($5, " ", $3);
361
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
362
    itex2MML_free_string(s1);
363
    itex2MML_free_string(s2);
364
  }
365
  else {
366
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
367
    char * s2 = itex2MML_copy3($5, " ", $3);
368
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
369
    itex2MML_free_string(s1);
370
    itex2MML_free_string(s2);
371
  }
372
  itex2MML_free_string($1);
373
  itex2MML_free_string($3);
374
  itex2MML_free_string($5);
375
}
376
| mob SUP closedTerm {
377
  if (itex2MML_displaymode == 1) {
378
    char * s1 = itex2MML_copy3("<mover>", $1, " ");
379
    $$ = itex2MML_copy3(s1, $3, "</mover>");
380
    itex2MML_free_string(s1);
381
  }
382
  else {
383
    char * s1 = itex2MML_copy3("<msup>", $1, " ");
384
    $$ = itex2MML_copy3(s1, $3, "</msup>");
385
    itex2MML_free_string(s1);
386
  }
387
  itex2MML_free_string($1);
388
  itex2MML_free_string($3);
389
}
390
|mib SUB closedTerm SUP closedTerm {
391
  if (itex2MML_displaymode == 1) {
392
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
393
    char * s2 = itex2MML_copy3($3, " ", $5);
394
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
395
    itex2MML_free_string(s1);
396
    itex2MML_free_string(s2);
397
  }
398
  else {
399
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
400
    char * s2 = itex2MML_copy3($3, " ", $5);
401
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
402
    itex2MML_free_string(s1);
403
    itex2MML_free_string(s2);
404
  }
405
  itex2MML_free_string($1);
406
  itex2MML_free_string($3);
407
  itex2MML_free_string($5);
408
}
409
| mib SUB closedTerm {
410
  if (itex2MML_displaymode == 1) {
411
    char * s1 = itex2MML_copy3("<munder>", $1, " ");
412
    $$ = itex2MML_copy3(s1, $3, "</munder>");
413
    itex2MML_free_string(s1);
414
  }
415
  else {
416
    char * s1 = itex2MML_copy3("<msub>", $1, " ");
417
    $$ = itex2MML_copy3(s1, $3, "</msub>");
418
    itex2MML_free_string(s1);
419
  }
420
  itex2MML_free_string($1);
421
  itex2MML_free_string($3);
422
}
423
| mib SUP closedTerm SUB closedTerm {
424
  if (itex2MML_displaymode == 1) {
425
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
426
    char * s2 = itex2MML_copy3($5, " ", $3);
427
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
428
    itex2MML_free_string(s1);
429
    itex2MML_free_string(s2);
430
  }
431
  else {
432
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
433
    char * s2 = itex2MML_copy3($5, " ", $3);
434
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
435
    itex2MML_free_string(s1);
436
    itex2MML_free_string(s2);
437
  }
438
  itex2MML_free_string($1);
439
  itex2MML_free_string($3);
440
  itex2MML_free_string($5);
441
}
442
| mib SUP closedTerm {
443
  if (itex2MML_displaymode == 1) {
444
    char * s1 = itex2MML_copy3("<mover>", $1, " ");
445
    $$ = itex2MML_copy3(s1, $3, "</mover>");
446
    itex2MML_free_string(s1);
447
  }
448
  else {
449
    char * s1 = itex2MML_copy3("<msup>", $1, " ");
450
    $$ = itex2MML_copy3(s1, $3, "</msup>");
451
    itex2MML_free_string(s1);
452
  }
453
  itex2MML_free_string($1);
454
  itex2MML_free_string($3);
455
}
456
| closedTerm SUB closedTerm SUP closedTerm {
457
  char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
458
  char * s2 = itex2MML_copy3($3, " ", $5);
459
  $$ = itex2MML_copy3(s1, s2, "</msubsup>");
460
  itex2MML_free_string(s1);
461
  itex2MML_free_string(s2);
462
  itex2MML_free_string($1);
463
  itex2MML_free_string($3);
464
  itex2MML_free_string($5);
465
}
466
| closedTerm SUP closedTerm SUB closedTerm {
467
  char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
468
  char * s2 = itex2MML_copy3($5, " ", $3);
469
  $$ = itex2MML_copy3(s1, s2, "</msubsup>");
470
  itex2MML_free_string(s1);
471
  itex2MML_free_string(s2);
472
  itex2MML_free_string($1);
473
  itex2MML_free_string($3);
474
  itex2MML_free_string($5);
475
}
476
| closedTerm SUB closedTerm {
477
  char * s1 = itex2MML_copy3("<msub>", $1, " ");
478
  $$ = itex2MML_copy3(s1, $3, "</msub>");
479
  itex2MML_free_string(s1);
480
  itex2MML_free_string($1);
481
  itex2MML_free_string($3);
482
}
483
| closedTerm SUP closedTerm {
484
  char * s1 = itex2MML_copy3("<msup>", $1, " ");
485
  $$ = itex2MML_copy3(s1, $3, "</msup>");
486
  itex2MML_free_string(s1);
487
  itex2MML_free_string($1);
488
  itex2MML_free_string($3);
489
}
490
| SUB closedTerm {
491
  $$ = itex2MML_copy3("<msub><mo></mo>", $2, "</msub>");
492
  itex2MML_free_string($2);
493
}
494
| SUP closedTerm {
495
  $$ = itex2MML_copy3("<msup><mo></mo>", $2, "</msup>");
496
  itex2MML_free_string($2);
497
}
498
| closedTerm {
499
  $$ = itex2MML_copy_string($1);
500
  itex2MML_free_string($1);
501
};
502
503
closedTerm: array
504
| unaryminus
505
| unaryplus
506
| mib
507
| mi {
508
  $$ = itex2MML_copy3("<mi>", $1, "</mi>");
509
  itex2MML_free_string($1);
510
}
511
| mn {
512
  $$ = itex2MML_copy3("<mn>", $1, "</mn>");
513
  itex2MML_free_string($1);
514
}
515
| mo 
516
| tensor
517
| multi
518
| mfrac
519
| binom
520
| msqrt 
521
| mroot
522
| munder
523
| mover
524
| bar
525
| vec
526
| hat
527
| dot
528
| ddot
529
| check
530
| tilde
531
| moverbrace
532
| munderbrace
533
| munderover
534
| emptymrow
535
| displaystyle
536
| textstyle
537
| textsize
538
| scriptsize
539
| scriptscriptsize
540
| italics
541
| bold
542
| roman
543
| rmchars
544
| bbold
545
| frak
546
| cal
547
| space
548
| textstring
549
| thinspace
550
| medspace
551
| thickspace
552
| quad
553
| qquad
554
| negspace
555
| phantom
556
| href
557
| statusline
558
| toggle
559
| fghighlight
560
| bghighlight
561
| color
562
| texover
563
| MROWOPEN closedTerm MROWCLOSE {
564
  $$ = itex2MML_copy_string($2);
565
  itex2MML_free_string($2);
566
}
567
| MROWOPEN compoundTermList MROWCLOSE {
568
  $$ = itex2MML_copy3("<mrow>", $2, "</mrow>");
569
  itex2MML_free_string($2);
570
}
571
| left compoundTermList right {
572
  char * s1 = itex2MML_copy3("<mrow>", $1, $2);
573
  $$ = itex2MML_copy3(s1, $3, "</mrow>");
574
  itex2MML_free_string(s1);
575
  itex2MML_free_string($1);
576
  itex2MML_free_string($2);
577
  itex2MML_free_string($3);
578
}
579
| mathenv
580
| substack
581
| pmod
582
| unrecognized;
583
584
left: LEFT LEFTDELIM {
585
  itex2MML_rowposn = 2;
586
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
587
  itex2MML_free_string($2);
588
}
589
| LEFT OTHERDELIM {
590
  itex2MML_rowposn = 2;
591
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
592
  itex2MML_free_string($2);
593
}
594
| LEFT PERIODDELIM {
595
  itex2MML_rowposn = 2;
596
  $$ = itex2MML_copy_string("");
597
  itex2MML_free_string($2);
598
};
599
600
right: RIGHT RIGHTDELIM {
601
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
602
  itex2MML_free_string($2);
603
}
604
| RIGHT OTHERDELIM {
605
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
606
  itex2MML_free_string($2);
607
}
608
| RIGHT PERIODDELIM {
609
  $$ = itex2MML_copy_string("");
610
  itex2MML_free_string($2);
611
};
612
613
bigdelim: BIG LEFTDELIM {
614
  itex2MML_rowposn = 2;
615
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
616
  itex2MML_free_string($2);
617
} 
618
| BIG RIGHTDELIM {
619
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
620
  itex2MML_free_string($2);
621
}
622
| BIG OTHERDELIM {
623
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
624
  itex2MML_free_string($2);
625
}
626
| BBIG LEFTDELIM {
627
  itex2MML_rowposn = 2;
628
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
629
  itex2MML_free_string($2);
630
}
631
| BBIG RIGHTDELIM {
632
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
633
  itex2MML_free_string($2);
634
}
635
| BBIG OTHERDELIM {
636
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
637
  itex2MML_free_string($2);
638
}
639
| BIGG LEFTDELIM {
640
  itex2MML_rowposn = 2;
641
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
642
  itex2MML_free_string($2);
643
} 
644
| BIGG RIGHTDELIM {
645
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
646
  itex2MML_free_string($2);
647
}
648
| BIGG OTHERDELIM {
649
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
650
  itex2MML_free_string($2);
651
}
652
| BBIGG LEFTDELIM {
653
  itex2MML_rowposn = 2;
654
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
655
  itex2MML_free_string($2);
656
}
657
| BBIGG RIGHTDELIM {
658
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
659
  itex2MML_free_string($2);
660
}
661
| BBIGG OTHERDELIM {
662
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
663
  itex2MML_free_string($2);
664
}
665
BIGL LEFTDELIM {
666
  itex2MML_rowposn = 2;
667
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
668
  itex2MML_free_string($2);
669
}
670
| BIGL OTHERDELIM {
671
  itex2MML_rowposn = 2;
672
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
673
  itex2MML_free_string($2);
674
}
675
| BBIGL LEFTDELIM {
676
  itex2MML_rowposn = 2;
677
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
678
  itex2MML_free_string($2);
679
}
680
| BBIGL OTHERDELIM {
681
  itex2MML_rowposn = 2;
682
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
683
  itex2MML_free_string($2);
684
}
685
| BIGGL LEFTDELIM {
686
  itex2MML_rowposn = 2;
687
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
688
  itex2MML_free_string($2);
689
} 
690
| BIGGL OTHERDELIM {
691
  itex2MML_rowposn = 2;
692
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
693
  itex2MML_free_string($2);
694
}
695
| BBIGGL LEFTDELIM {
696
  itex2MML_rowposn = 2;
697
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
698
  itex2MML_free_string($2);
699
}
700
| BBIGGL OTHERDELIM {
701
  itex2MML_rowposn = 2;
702
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
703
  itex2MML_free_string($2);
704
};
705
706
unrecognized: UNKNOWNCHAR {
707
  $$ = itex2MML_copy_string("<merror><mtext>Unknown character</mtext></merror>");
708
};
709
710
unaryminus: UNARYMINUS {
711
  $$ = itex2MML_copy_string("<mo lspace=\"verythinmathspace\" rspace=\"0em\">&minus;</mo>");
712
};
713
714
unaryplus: UNARYPLUS {
715
  $$ = itex2MML_copy_string("<mo lspace=\"verythinmathspace\" rspace=\"0em\">+</mo>");
716
};
717
718
mi: MI;
719
720
mib: MIB {
721
  itex2MML_rowposn=2;
722
  $$ = itex2MML_copy3("<mi>", $1, "</mi>");
723
  itex2MML_free_string($1);
724
};
725
726
mn: MN;
727
728
mob: MOB {
729
  itex2MML_rowposn = 2;
730
  $$ = itex2MML_copy3("<mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">", $1, "</mo>");
731
  itex2MML_free_string($1);
732
};
733
734
mo: mob
735
| bigdelim
736
| MO {
737
  itex2MML_rowposn = 2;
738
  $$ = itex2MML_copy3("<mo>", $1, "</mo>");
739
  itex2MML_free_string($1);
740
}
741
| MOL {
742
  itex2MML_rowposn = 2;
743
  $$ = itex2MML_copy3("<mo>", $1, "</mo>");
744
  itex2MML_free_string($1);
745
}
746
| RIGHTDELIM {
747
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
748
  itex2MML_free_string($1);
749
}
750
| LEFTDELIM {
751
  itex2MML_rowposn = 2;
752
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
753
  itex2MML_free_string($1);
754
}
755
| OTHERDELIM {
756
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
757
  itex2MML_free_string($1);
758
}
759
| MOF {
760
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
761
  itex2MML_free_string($1);
762
}
763
| PERIODDELIM {
764
  $$ = itex2MML_copy3("<mo>", $1, "</mo>");
765
  itex2MML_free_string($1);
766
}
767
| MOS {
768
  itex2MML_rowposn=2;
769
  $$ = itex2MML_copy3("<mo lspace=\"mediummathspace\" rspace=\"mediummathspace\">", $1, "</mo>");
770
  itex2MML_free_string($1);
771
}
772
| MOP {
773
  itex2MML_rowposn = 2;
774
  $$ = itex2MML_copy3("<mo lspace=\"0em\" rspace=\"thinmathspace\">", $1, "</mo>");
775
  itex2MML_free_string($1);
776
}
777
| MATHOP TEXTSTRING {
778
  itex2MML_rowposn = 2;
779
  $$ = itex2MML_copy3("<mo lspace=\"0em\" rspace=\"thinmathspace\">", $2, "</mo>");
780
  itex2MML_free_string($2);
781
};
782
783
emptymrow: EMPTYMROW {
784
  $$ = itex2MML_copy_string("<mrow></mrow>");
785
};
786
787
space: SPACE ST INTONE END ST INTTWO END ST INTTHREE END {
788
  char * s1 = itex2MML_copy3("<mspace height=\"", $3, "ex\" depth=\"");
789
  char * s2 = itex2MML_copy3($6, "ex\" width=\"", $9);
790
  $$ = itex2MML_copy3(s1, s2, "em\"></mspace>");
791
  itex2MML_free_string(s1);
792
  itex2MML_free_string(s2);
793
  itex2MML_free_string($3);
794
  itex2MML_free_string($6);
795
  itex2MML_free_string($9);
796
};
797
798
statusline: STATLINE TEXTSTRING closedTerm {
799
  char * s1 = itex2MML_copy3("<maction actiontype=\"statusline\">", $3, "<mtext>");
800
  $$ = itex2MML_copy3(s1, $2, "</mtext></maction>");
801
  itex2MML_free_string(s1);
802
  itex2MML_free_string($2);
803
  itex2MML_free_string($3);
804
};
805
806
toggle: TOGGLE closedTerm closedTerm {
807
  char * s1 = itex2MML_copy3("<maction actiontype=\"toggle\" selection=\"2\">", $2, " ");
808
  $$ = itex2MML_copy3(s1, $3, "</maction>");
809
  itex2MML_free_string(s1);
810
  itex2MML_free_string($2);
811
  itex2MML_free_string($3);
812
};
813
814
fghighlight: FGHIGHLIGHT ATTRLIST closedTerm {
815
  char * s1 = itex2MML_copy3("<maction actiontype=\"highlight\" other='color=", $2, "'>");
816
  $$ = itex2MML_copy3(s1, $3, "</maction>");
817
  itex2MML_free_string(s1);
818
  itex2MML_free_string($2);
819
  itex2MML_free_string($3);
820
};
821
822
bghighlight: BGHIGHLIGHT ATTRLIST closedTerm {
823
  char * s1 = itex2MML_copy3("<maction actiontype=\"highlight\" other='background=", $2, "'>");
824
  $$ = itex2MML_copy3(s1, $3, "</maction>");
825
  itex2MML_free_string(s1);
826
  itex2MML_free_string($2);
827
  itex2MML_free_string($3);
828
};
829
830
color: COLOR ATTRLIST compoundTermList {
831
  char * s1 = itex2MML_copy3("<mstyle mathcolor=", $2, ">");
832
  $$ = itex2MML_copy3(s1, $3, "</mstyle>");
833
  itex2MML_free_string(s1);
834
  itex2MML_free_string($2);
835
  itex2MML_free_string($3);
836
}
837
| BGCOLOR ATTRLIST compoundTermList {
838
  char * s1 = itex2MML_copy3("<mstyle mathbackground=", $2, ">");
839
  $$ = itex2MML_copy3(s1, $3, "</mstyle>");
840
  itex2MML_free_string(s1);
841
  itex2MML_free_string($2);
842
  itex2MML_free_string($3);
843
};
844
845
textstring: TEXTBOX TEXTSTRING {
846
  $$ = itex2MML_copy3("<mtext>", $2, "</mtext>");
847
  itex2MML_free_string($2);
848
};
849
850
displaystyle: DISPLAY closedTerm {
851
  $$ = itex2MML_copy3("<mstyle displaystyle=\"true\">", $2, "</mstyle>");
852
  itex2MML_free_string($2);
853
};
854
855
textstyle: TEXTSTY closedTerm {
856
  $$ = itex2MML_copy3("<mstyle displaystyle=\"false\">", $2, "</mstyle>");
857
  itex2MML_free_string($2);
858
};
859
860
textsize: TEXTSIZE closedTerm {
861
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"0\">", $2, "</mstyle>");
862
  itex2MML_free_string($2);
863
};
864
865
scriptsize: SCSIZE closedTerm {
866
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"1\">", $2, "</mstyle>");
867
  itex2MML_free_string($2);
868
};
869
870
scriptscriptsize: SCSCSIZE closedTerm {
871
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"2\">", $2, "</mstyle>");
872
  itex2MML_free_string($2);
873
};
874
875
italics: ITALICS closedTerm {
876
  $$ = itex2MML_copy3("<mstyle mathvariant=\"italic\">", $2, "</mstyle>");
877
  itex2MML_free_string($2);
878
};
879
880
bold: BOLD closedTerm {
881
  $$ = itex2MML_copy3("<mstyle mathvariant=\"bold\">", $2, "</mstyle>");
882
  itex2MML_free_string($2);
883
};
884
885
roman: RM ST rmchars END {
886
  $$ = itex2MML_copy3("<mi mathvariant=\"normal\">", $3, "</mi>");
887
  itex2MML_free_string($3);
888
};
889
890
rmchars: RMCHAR {
891
  $$ = itex2MML_copy_string($1);
892
  itex2MML_free_string($1);
893
}
894
| rmchars RMCHAR {
895
  $$ = itex2MML_copy2($1, $2);
896
  itex2MML_free_string($1);
897
  itex2MML_free_string($2);
898
};
899
900
bbold: BB ST bbletters END {
901
  $$ = itex2MML_copy3("<mi>", $3, "</mi>");
902
  itex2MML_free_string($3);
903
};
904
905
bbletters: bbletter {
906
  $$ = itex2MML_copy_string($1);
907
  itex2MML_free_string($1);
908
}
909
| bbletters bbletter {
910
  $$ = itex2MML_copy2($1, $2);
911
  itex2MML_free_string($1);
912
  itex2MML_free_string($2);
913
};
914
915
bbletter: BBLOWERCHAR {
916
  $$ = itex2MML_copy_string($1);
917
  itex2MML_free_string($1);
918
}
919
| BBUPPERCHAR {
920
  $$ = itex2MML_copy3("&", $1, "opf;");
921
  itex2MML_free_string($1);
922
};
923
924
frak: FRAK ST frakletters END {
925
  $$ = itex2MML_copy3("<mi>", $3, "</mi>");
926
  itex2MML_free_string($3);
927
};
928
929
frakletters: frakletter {
930
  $$ = itex2MML_copy_string($1);
931
  itex2MML_free_string($1);
932
}
933
| frakletters frakletter {
934
  $$ = itex2MML_copy2($1, $2);
935
  itex2MML_free_string($1);
936
  itex2MML_free_string($2);
937
};
938
939
frakletter: FRAKCHAR {
940
  $$ = itex2MML_copy3("&", $1, "fr;");
941
  itex2MML_free_string($1);
942
};
943
944
cal: CAL ST calletters END {
945
  $$ = itex2MML_copy3("<mi>", $3, "</mi>");
946
  itex2MML_free_string($3);
947
};
948
949
calletters: calletter {
950
  $$ = itex2MML_copy_string($1);
951
  itex2MML_free_string($1);
952
}
953
| calletters calletter {
954
  $$ = itex2MML_copy2($1, $2);
955
  itex2MML_free_string($1);
956
  itex2MML_free_string($2);
957
};
958
959
calletter: CALCHAR {
960
  $$ = itex2MML_copy3("&", $1, "scr;");
961
  itex2MML_free_string($1);
962
};
963
964
thinspace: THINSPACE {
965
  $$ = itex2MML_copy_string("<mspace width=\"thinmathspace\"></mspace>");
966
};
967
968
medspace: MEDSPACE {
969
  $$ = itex2MML_copy_string("<mspace width=\"mediummathspace\"></mspace>");
970
};
971
972
thickspace: THICKSPACE {
973
  $$ = itex2MML_copy_string("<mspace width=\"thickmathspace\"></mspace>");
974
};
975
976
quad: QUAD {
977
  $$ = itex2MML_copy_string("<mspace width=\"1em\"></mspace>");
978
};
979
980
qquad: QQUAD {
981
  $$ = itex2MML_copy_string("<mspace width=\"2em\"></mspace>");
982
};
983
984
negspace: NEGSPACE {
985
  $$ = itex2MML_copy_string("<mspace width=\"-0.1667 em\"></mspace>");
986
};
987
988
phantom: PHANTOM closedTerm {
989
  $$ = itex2MML_copy3("<mphantom>", $2, "</mphantom>");
990
  itex2MML_free_string($2);
991
};
992
993
href: HREF TEXTSTRING closedTerm {
994
  char * s1 = itex2MML_copy3("<mrow xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"", $2, "\">");
995
  $$ = itex2MML_copy3(s1, $3, "</mrow>");
996
  itex2MML_free_string(s1);
997
  itex2MML_free_string($2);
998
  itex2MML_free_string($3);
999
};
1000
1001
tensor: TENSOR closedTerm MROWOPEN subsupList MROWCLOSE {
1002
  char * s1 = itex2MML_copy3("<mmultiscripts>", $2, $4);
1003
  $$ = itex2MML_copy2(s1, "</mmultiscripts>");
1004
  itex2MML_free_string(s1);
1005
  itex2MML_free_string($2);
1006
  itex2MML_free_string($4);
1007
}
1008
| TENSOR closedTerm subsupList {
1009
  char * s1 = itex2MML_copy3("<mmultiscripts>", $2, $3);
1010
  $$ = itex2MML_copy2(s1, "</mmultiscripts>");
1011
  itex2MML_free_string(s1);
1012
  itex2MML_free_string($2);
1013
  itex2MML_free_string($3);
1014
};
1015
1016
multi: MULTI MROWOPEN subsupList MROWCLOSE closedTerm MROWOPEN subsupList MROWCLOSE {
1017
  char * s1 = itex2MML_copy3("<mmultiscripts>", $5, $7);
1018
  char * s2 = itex2MML_copy3("<mprescripts></mprescripts>", $3, "</mmultiscripts>");
1019
  $$ = itex2MML_copy2(s1, s2);
1020
  itex2MML_free_string(s1);
1021
  itex2MML_free_string(s2);
1022
  itex2MML_free_string($3);
1023
  itex2MML_free_string($5);
1024
  itex2MML_free_string($7);
1025
}
1026
| MULTI MROWOPEN subsupList MROWCLOSE closedTerm EMPTYMROW {
1027
  char * s1 = itex2MML_copy2("<mmultiscripts>", $5);
1028
  char * s2 = itex2MML_copy3("<mprescripts></mprescripts>", $3, "</mmultiscripts>");
1029
  $$ = itex2MML_copy2(s1, s2);
1030
  itex2MML_free_string(s1);
1031
  itex2MML_free_string(s2);
1032
  itex2MML_free_string($3);
1033
  itex2MML_free_string($5);
1034
}
1035
| MULTI EMPTYMROW closedTerm MROWOPEN subsupList MROWCLOSE {
1036
  char * s1 = itex2MML_copy3("<mmultiscripts>", $3, $5);
1037
  $$ = itex2MML_copy2(s1, "</mmultiscripts>");
1038
  itex2MML_free_string(s1);
1039
  itex2MML_free_string($3);
1040
  itex2MML_free_string($5); 
1041
};
1042
1043
subsupList: subsupTerm {
1044
  $$ = itex2MML_copy_string($1);
1045
  itex2MML_free_string($1);
1046
}
1047
| subsupList subsupTerm {
1048
  $$ = itex2MML_copy3($1, " ", $2);
1049
  itex2MML_free_string($1);
1050
  itex2MML_free_string($2);
1051
};
1052
1053
subsupTerm: SUB closedTerm SUP closedTerm {
1054
  $$ = itex2MML_copy3($2, " ", $4);
1055
  itex2MML_free_string($2);
1056
  itex2MML_free_string($4);
1057
}
1058
| SUB closedTerm {
1059
  $$ = itex2MML_copy2($2, " <none></none>");
1060
  itex2MML_free_string($2);
1061
}
1062
| SUP closedTerm {
1063
  $$ = itex2MML_copy2("<none></none> ", $2);
1064
  itex2MML_free_string($2);
1065
}
1066
| SUB SUP closedTerm {
1067
  $$ = itex2MML_copy2("<none></none> ", $3);
1068
  itex2MML_free_string($3);
1069
};
1070
1071
mfrac: FRAC closedTerm closedTerm {
1072
  char * s1 = itex2MML_copy3("<mfrac>", $2, $3);
1073
  $$ = itex2MML_copy2(s1, "</mfrac>");
1074
  itex2MML_free_string(s1);
1075
  itex2MML_free_string($2);
1076
  itex2MML_free_string($3);
1077
}
1078
| TFRAC closedTerm closedTerm {
1079
  char * s1 = itex2MML_copy3("<mstyle displaystyle=\"false\"><mfrac>", $2, $3);
1080
  $$ = itex2MML_copy2(s1, "</mfrac></mstyle>");
1081
  itex2MML_free_string(s1);
1082
  itex2MML_free_string($2);
1083
  itex2MML_free_string($3);
1084
};
1085
1086
pmod: PMOD closedTerm {
1087
  $$ = itex2MML_copy3( "<mo lspace=\"mediummathspace\">(</mo><mo rspace=\"thinmathspace\">mod</mo>", $2, "<mo rspace=\"mediummathspace\">)</mo>");
1088
  itex2MML_free_string($2);
1089
}
1090
1091
texover: MROWOPEN compoundTermList TEXOVER compoundTermList MROWCLOSE {
1092
  char * s1 = itex2MML_copy3("<mfrac><mrow>", $2, "</mrow><mrow>");
1093
  $$ = itex2MML_copy3(s1, $4, "</mrow></mfrac>");
1094
  itex2MML_free_string(s1);
1095
  itex2MML_free_string($2);
1096
  itex2MML_free_string($4);
1097
}
1098
| left compoundTermList TEXOVER compoundTermList right {
1099
  char * s1 = itex2MML_copy3("<mrow>", $1, "<mfrac><mrow>");
1100
  char * s2 = itex2MML_copy3($2, "</mrow><mrow>", $4);
1101
  char * s3 = itex2MML_copy3("</mrow></mfrac>", $5, "</mrow>");
1102
  $$ = itex2MML_copy3(s1, s2, s3);
1103
  itex2MML_free_string(s1);
1104
  itex2MML_free_string(s2);
1105
  itex2MML_free_string(s3);
1106
  itex2MML_free_string($1);
1107
  itex2MML_free_string($2);
1108
  itex2MML_free_string($4);
1109
  itex2MML_free_string($5);
1110
};
1111
1112
binom: BINOM closedTerm closedTerm {
1113
  char * s1 = itex2MML_copy3("<mfrac linethickness=\"0\">", $2, $3);
1114
  $$ = itex2MML_copy2(s1, "</mfrac>");
1115
  itex2MML_free_string(s1);
1116
  itex2MML_free_string($2);
1117
  itex2MML_free_string($3);
1118
};
1119
1120
munderbrace: UNDERBRACE closedTerm {
1121
  $$ = itex2MML_copy3("<munder>", $2, "<mo>&UnderBrace;</mo></munder>");
1122
  itex2MML_free_string($2);
1123
};
1124
1125
moverbrace: OVERBRACE closedTerm {
1126
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&OverBrace;</mo></mover>");
1127
  itex2MML_free_string($2);
1128
};
1129
1130
bar: BAR closedTerm {
1131
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&OverBar;</mo></mover>");
1132
  itex2MML_free_string($2);
1133
}
1134
| WIDEBAR closedTerm {
1135
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&OverBar;</mo></mover>");
1136
  itex2MML_free_string($2);
1137
};
1138
1139
vec: VEC closedTerm {
1140
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&RightVector;</mo></mover>");
1141
  itex2MML_free_string($2);
1142
}
1143
| WIDEVEC closedTerm {
1144
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&RightVector;</mo></mover>");
1145
  itex2MML_free_string($2);
1146
};
1147
1148
dot: DOT closedTerm {
1149
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&dot;</mo></mover>");
1150
  itex2MML_free_string($2);
1151
};
1152
1153
ddot: DDOT closedTerm {
1154
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&Dot;</mo></mover>");
1155
  itex2MML_free_string($2);
1156
};
1157
1158
tilde: TILDE closedTerm {
1159
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&tilde;</mo></mover>");
1160
  itex2MML_free_string($2);
1161
}
1162
| WIDETILDE closedTerm {
1163
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&tilde;</mo></mover>");
1164
  itex2MML_free_string($2);
1165
};
1166
1167
check: CHECK closedTerm {
1168
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&macr;</mo></mover>");
1169
  itex2MML_free_string($2);
1170
}
1171
| WIDECHECK closedTerm {
1172
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&macr;</mo></mover>");
1173
  itex2MML_free_string($2);
1174
};
1175
1176
hat: HAT closedTerm {
1177
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&#x302;</mo></mover>");
1178
  itex2MML_free_string($2);
1179
}
1180
| WIDEHAT closedTerm {
1181
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&#x302;</mo></mover>");
1182
  itex2MML_free_string($2);
1183
};
1184
1185
msqrt: SQRT closedTerm {
1186
  $$ = itex2MML_copy3("<msqrt>", $2, "</msqrt>");
1187
  itex2MML_free_string($2);
1188
};
1189
1190
mroot: ROOT closedTerm closedTerm {
1191
  char * s1 = itex2MML_copy3("<mroot>", $3, $2);
1192
  $$ = itex2MML_copy2(s1, "</mroot>");
1193
  itex2MML_free_string(s1);
1194
  itex2MML_free_string($2);
1195
  itex2MML_free_string($3);
1196
};
1197
1198
munder: UNDER closedTerm closedTerm {
1199
  char * s1 = itex2MML_copy3("<munder>", $3, $2);
1200
  $$ = itex2MML_copy2(s1, "</munder>");
1201
  itex2MML_free_string(s1);
1202
  itex2MML_free_string($2);
1203
  itex2MML_free_string($3);
1204
};
1205
1206
mover: OVER closedTerm closedTerm {
1207
  char * s1 = itex2MML_copy3("<mover>", $3, $2);
1208
  $$ = itex2MML_copy2(s1, "</mover>");
1209
  itex2MML_free_string(s1);
1210
  itex2MML_free_string($2);
1211
  itex2MML_free_string($3);
1212
};
1213
1214
munderover: UNDEROVER closedTerm closedTerm closedTerm {
1215
  char * s1 = itex2MML_copy3("<munderover>", $4, $2);
1216
  $$ = itex2MML_copy3(s1, $3, "</munderover>");
1217
  itex2MML_free_string(s1);
1218
  itex2MML_free_string($2);
1219
  itex2MML_free_string($3);
1220
  itex2MML_free_string($4);
1221
};
1222
1223
mathenv: BEGINENV MATRIX tableRowList ENDENV MATRIX {
1224
  $$ = itex2MML_copy3("<mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow>");
1225
  itex2MML_free_string($3);
1226
}
1227
| BEGINENV PMATRIX tableRowList ENDENV PMATRIX {
1228
  $$ = itex2MML_copy3("<mrow><mo>(</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>)</mo></mrow>");
1229
  itex2MML_free_string($3);
1230
}
1231
| BEGINENV BMATRIX tableRowList ENDENV BMATRIX {
1232
  $$ = itex2MML_copy3("<mrow><mo>[</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>]</mo></mrow>");
1233
  itex2MML_free_string($3);
1234
}
1235
| BEGINENV VMATRIX tableRowList ENDENV VMATRIX {
1236
  $$ = itex2MML_copy3("<mrow><mo>&VerticalBar;</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>&VerticalBar;</mo></mrow>");
1237
  itex2MML_free_string($3);
1238
}
1239
| BEGINENV BBMATRIX tableRowList ENDENV BBMATRIX {
1240
  $$ = itex2MML_copy3("<mrow><mo>{</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>}</mo></mrow>");
1241
  itex2MML_free_string($3);
1242
}
1243
| BEGINENV VVMATRIX tableRowList ENDENV VVMATRIX {
1244
  $$ = itex2MML_copy3("<mrow><mo>&DoubleVerticalBar;</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>&DoubleVerticalBar;</mo></mrow>");
1245
  itex2MML_free_string($3);
1246
}
1247
| BEGINENV SMALLMATRIX tableRowList ENDENV SMALLMATRIX {
1248
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"2\"><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow></mstyle>");
1249
  itex2MML_free_string($3);
1250
}
1251
| BEGINENV CASES tableRowList ENDENV CASES {
1252
  $$ = itex2MML_copy3("<mrow><mo>{</mo><mrow><mtable columnalign=\"left left\">", $3, "</mtable></mrow></mrow>");
1253
  itex2MML_free_string($3);
1254
}
1255
| BEGINENV ALIGNED tableRowList ENDENV ALIGNED {
1256
  $$ = itex2MML_copy3("<mrow><mtable columnalign=\"right left\">", $3, "</mtable></mrow>");
1257
  itex2MML_free_string($3);
1258
};
1259
1260
substack: SUBSTACK MROWOPEN tableRowList MROWCLOSE {
1261
  $$ = itex2MML_copy3("<mrow><mtable columnalign=\"center\" rowspacing=\"0.5ex\">", $3, "</mtable></mrow>");
1262
  itex2MML_free_string($3);
1263
};
1264
1265
array: ARRAY MROWOPEN tableRowList MROWCLOSE {
1266
  $$ = itex2MML_copy3("<mrow><mtable>", $3, "</mtable></mrow>");
1267
  itex2MML_free_string($3);
1268
}
1269
| ARRAY MROWOPEN ARRAYOPTS MROWOPEN arrayopts MROWCLOSE tableRowList MROWCLOSE {
1270
  char * s1 = itex2MML_copy3("<mrow><mtable ", $5, ">");
1271
  $$ = itex2MML_copy3(s1, $7, "</mtable></mrow>");
1272
  itex2MML_free_string(s1);
1273
  itex2MML_free_string($5);
1274
  itex2MML_free_string($7);
1275
};
1276
1277
arrayopts: anarrayopt {
1278
  $$ = itex2MML_copy_string($1);
1279
  itex2MML_free_string($1);
1280
}
1281
| arrayopts anarrayopt {
1282
  $$ = itex2MML_copy3($1, " ", $2);
1283
  itex2MML_free_string($1);
1284
  itex2MML_free_string($2);
1285
};
1286
1287
anarrayopt: collayout {
1288
  $$ = itex2MML_copy_string($1);
1289
  itex2MML_free_string($1);
1290
}
1291
| colalign {
1292
  $$ = itex2MML_copy_string($1);
1293
  itex2MML_free_string($1);
1294
}
1295
| rowalign {
1296
  $$ = itex2MML_copy_string($1);
1297
  itex2MML_free_string($1);
1298
}
1299
| align {
1300
  $$ = itex2MML_copy_string($1);
1301
  itex2MML_free_string($1);
1302
}
1303
| eqrows {
1304
  $$ = itex2MML_copy_string($1);
1305
  itex2MML_free_string($1);
1306
}
1307
| eqcols {
1308
  $$ = itex2MML_copy_string($1);
1309
  itex2MML_free_string($1);
1310
}
1311
| rowlines {
1312
  $$ = itex2MML_copy_string($1);
1313
  itex2MML_free_string($1);
1314
}
1315
| collines {
1316
  $$ = itex2MML_copy_string($1);
1317
  itex2MML_free_string($1);
1318
}
1319
| frame {
1320
  $$ = itex2MML_copy_string($1);
1321
  itex2MML_free_string($1);
1322
}
1323
| padding {
1324
  $$ = itex2MML_copy_string($1);
1325
  itex2MML_free_string($1);
1326
};
1327
1328
collayout: COLLAYOUT ATTRLIST {
1329
  $$ = itex2MML_copy2("columnalign=", $2);
1330
  itex2MML_free_string($2);
1331
};
1332
1333
colalign: COLALIGN ATTRLIST {
1334
  $$ = itex2MML_copy2("columnalign=", $2);
1335
  itex2MML_free_string($2);
1336
};
1337
1338
rowalign: ROWALIGN ATTRLIST {
1339
  $$ = itex2MML_copy2("rowalign=", $2);
1340
  itex2MML_free_string($2);
1341
};
1342
1343
align: ALIGN ATTRLIST {
1344
  $$ = itex2MML_copy2("align=", $2);
1345
  itex2MML_free_string($2);
1346
};
1347
1348
eqrows: EQROWS ATTRLIST {
1349
  $$ = itex2MML_copy2("equalrows=", $2);
1350
  itex2MML_free_string($2);
1351
};
1352
1353
eqcols: EQCOLS ATTRLIST {
1354
  $$ = itex2MML_copy2("equalcolumns=", $2);
1355
  itex2MML_free_string($2);
1356
};
1357
1358
rowlines: ROWLINES ATTRLIST {
1359
  $$ = itex2MML_copy2("rowlines=", $2);
1360
  itex2MML_free_string($2);
1361
};
1362
1363
collines: COLLINES ATTRLIST {
1364
  $$ = itex2MML_copy2("columnlines=", $2);
1365
  itex2MML_free_string($2);
1366
};
1367
1368
frame: FRAME ATTRLIST {
1369
  $$ = itex2MML_copy2("frame=", $2);
1370
  itex2MML_free_string($2);
1371
};
1372
1373
padding: PADDING ATTRLIST {
1374
  char * s1 = itex2MML_copy3("rowspacing=", $2, " columnspacing=");
1375
  $$ = itex2MML_copy2(s1, $2);
1376
  itex2MML_free_string(s1);
1377
  itex2MML_free_string($2);
1378
};
1379
1380
tableRowList: tableRow {
1381
  $$ = itex2MML_copy_string($1);
1382
  itex2MML_free_string($1);
1383
}
1384
| tableRowList ROWSEP tableRow {
1385
  $$ = itex2MML_copy3($1, " ", $3);
1386
  itex2MML_free_string($1);
1387
  itex2MML_free_string($3);
1388
};
1389
1390
tableRow: simpleTableRow {
1391
  $$ = itex2MML_copy3("<mtr>", $1, "</mtr>");
1392
  itex2MML_free_string($1);
1393
}
1394
| optsTableRow {
1395
  $$ = itex2MML_copy_string($1);
1396
  itex2MML_free_string($1);
1397
};
1398
1399
simpleTableRow: tableCell {
1400
  $$ = itex2MML_copy_string($1);
1401
  itex2MML_free_string($1);
1402
}
1403
| simpleTableRow COLSEP tableCell {
1404
  $$ = itex2MML_copy3($1, " ", $3);
1405
  itex2MML_free_string($1);
1406
  itex2MML_free_string($3);
1407
};
1408
1409
optsTableRow: ROWOPTS MROWOPEN rowopts MROWCLOSE simpleTableRow {
1410
  char * s1 = itex2MML_copy3("<mtr ", $3, ">");
1411
  $$ = itex2MML_copy3(s1, $5, "</mtr>");
1412
  itex2MML_free_string(s1);
1413
  itex2MML_free_string($3);
1414
  itex2MML_free_string($5);
1415
};
1416
1417
rowopts: arowopt {
1418
  $$ = itex2MML_copy_string($1);
1419
  itex2MML_free_string($1);
1420
}
1421
| rowopts arowopt {
1422
  $$ = itex2MML_copy3($1, " ", $2);
1423
  itex2MML_free_string($1);
1424
  itex2MML_free_string($2);
1425
};
1426
1427
arowopt: colalign {
1428
  $$ = itex2MML_copy_string($1);
1429
  itex2MML_free_string($1);
1430
}
1431
| rowalign {
1432
  $$ = itex2MML_copy_string($1);
1433
  itex2MML_free_string($1);
1434
};
1435
1436
tableCell:   {
1437
  $$ = itex2MML_copy_string("<mtd></mtd>");
1438
}
1439
| compoundTermList {
1440
  $$ = itex2MML_copy3("<mtd>", $1, "</mtd>");
1441
  itex2MML_free_string($1);
1442
}
1443
| CELLOPTS MROWOPEN cellopts MROWCLOSE compoundTermList {
1444
  char * s1 = itex2MML_copy3("<mtd ", $3, ">");
1445
  $$ = itex2MML_copy3(s1, $5, "</mtd>");
1446
  itex2MML_free_string(s1);
1447
  itex2MML_free_string($3);
1448
  itex2MML_free_string($5);
1449
};
1450
1451
cellopts: acellopt {
1452
  $$ = itex2MML_copy_string($1);
1453
  itex2MML_free_string($1);
1454
}
1455
| cellopts acellopt {
1456
  $$ = itex2MML_copy3($1, " ", $2);
1457
  itex2MML_free_string($1);
1458
  itex2MML_free_string($2);
1459
};
1460
1461
acellopt: colalign {
1462
  $$ = itex2MML_copy_string($1);
1463
  itex2MML_free_string($1);
1464
}
1465
| rowalign {
1466
  $$ = itex2MML_copy_string($1);
1467
  itex2MML_free_string($1);
1468
}
1469
| rowspan {
1470
  $$ = itex2MML_copy_string($1);
1471
  itex2MML_free_string($1);
1472
}
1473
| colspan {
1474
  $$ = itex2MML_copy_string($1);
1475
  itex2MML_free_string($1);
1476
};
1477
1478
rowspan: ROWSPAN ATTRLIST {
1479
  $$ = itex2MML_copy2("rowspan=", $2);
1480
  itex2MML_free_string($2);
1481
};
1482
1483
colspan: COLSPAN ATTRLIST {
1484
  $$ = itex2MML_copy2("colspan=", $2);
1485
  itex2MML_free_string($2);
1486
};
1487
1488
%%
1489
1490
char * itex2MML_parse (const char * buffer, unsigned long length)
1491
{
1492
  char * mathml = 0;
1493
1494
  int result;
1495
1496
  itex2MML_setup (buffer, length);
1497
  itex2MML_restart ();
1498
1499
  result = itex2MML_yyparse (&mathml);
1500
1501
  if (result && mathml) /* shouldn't happen? */
1502
    {
1503
      itex2MML_free_string (mathml);
1504
      mathml = 0;
1505
    }
1506
  return mathml;
1507
}
1508
1509
int itex2MML_filter (const char * buffer, unsigned long length)
1510
{
1511
  itex2MML_setup (buffer, length);
1512
  itex2MML_restart ();
1513
1514
  return itex2MML_yyparse (0);
1515
}
1516
1517
#define ITEX_DELIMITER_DOLLAR 0
1518
#define ITEX_DELIMITER_DOUBLE 1
1519
#define ITEX_DELIMITER_SQUARE 2
1520
1521
static char * itex2MML_last_error = 0;
1522
1523
static void itex2MML_keep_error (const char * msg)
1524
{
1525
  if (itex2MML_last_error)
1526
    {
1527
      itex2MML_free_string (itex2MML_last_error);
1528
      itex2MML_last_error = 0;
1529
    }
1530
  itex2MML_last_error = itex2MML_copy_escaped (msg);
1531
}
1532
1533
int itex2MML_html_filter (const char * buffer, unsigned long length)
1534
{
1535
  int result = 0;
1536
1537
  int type = 0;
1538
  int skip = 0;
1539
  int match = 0;
1540
1541
  const char * ptr1 = buffer;
1542
  const char * ptr2 = 0;
1543
1544
  const char * end = buffer + length;
1545
1546
  char * mathml = 0;
1547
1548
  void (*save_error_fn) (const char * msg) = itex2MML_error;
1549
1550
  itex2MML_error = itex2MML_keep_error;
1551
1552
 _until_math:
1553
  ptr2 = ptr1;
1554
1555
  while (ptr2 < end)
1556
    {
1557
      if (*ptr2 == '$') break;
1558
      if ((*ptr2 == '\\') && (ptr2 + 1 < end))
1559
	{
1560
	  if (*(ptr2+1) == '[') break;
1561
	}
1562
      ++ptr2;
1563
    }
1564
  if (itex2MML_write)
1565
    (*itex2MML_write) (ptr1, ptr2 - ptr1);
1566
1567
  if (ptr2 == end) goto _finish;
1568
1569
 _until_html:
1570
  ptr1 = ptr2;
1571
1572
  if (ptr2 + 1 < end)
1573
    {
1574
      if ((*ptr2 == '\\') && (*(ptr2+1) == '['))
1575
	{
1576
	  type = ITEX_DELIMITER_SQUARE;
1577
	  ptr2 += 2;
1578
	}
1579
      else if ((*ptr2 == '$') && (*(ptr2+1) == '$'))
1580
	{
1581
	  type = ITEX_DELIMITER_DOUBLE;
1582
	  ptr2 += 2;
1583
	}
1584
      else
1585
	{
1586
	  type = ITEX_DELIMITER_DOLLAR;
1587
	  ptr2 += 2;
1588
	}
1589
    }
1590
  else goto _finish;
1591
1592
  skip = 0;
1593
  match = 0;
1594
1595
  while (ptr2 < end)
1596
    {
1597
      switch (*ptr2)
1598
	{
1599
	case '<':
1600
	case '>':
1601
	  skip = 1;
1602
	  break;
1603
1604
	case '\\':
1605
	  if (ptr2 + 1 < end)
1606
	    {
1607
	      if (*(ptr2 + 1) == '[')
1608
		{
1609
		  skip = 1;
1610
		}
1611
	      else if (*(ptr2 + 1) == ']')
1612
		{
1613
		  if (type == ITEX_DELIMITER_SQUARE)
1614
		    {
1615
		      ptr2 += 2;
1616
		      match = 1;
1617
		    }
1618
		  else
1619
		    {
1620
		      skip = 1;
1621
		    }
1622
		}
1623
	    }
1624
	  break;
1625
1626
	case '$':
1627
	  if (type == ITEX_DELIMITER_SQUARE)
1628
	    {
1629
	      skip = 1;
1630
	    }
1631
	  else if (ptr2 + 1 < end)
1632
	    {
1633
	      if (*(ptr2 + 1) == '$')
1634
		{
1635
		  if (type == ITEX_DELIMITER_DOLLAR)
1636
		    {
1637
		      ptr2++;
1638
		      match = 1;
1639
		    }
1640
		  else
1641
		    {
1642
		      ptr2 += 2;
1643
		      match = 1;
1644
		    }
1645
		}
1646
	      else
1647
		{
1648
		  if (type == ITEX_DELIMITER_DOLLAR)
1649
		    {
1650
		      ptr2++;
1651
		      match = 1;
1652
		    }
1653
		  else
1654
		    {
1655
		      skip = 1;
1656
		    }
1657
		}
1658
	    }
1659
	  else
1660
	    {
1661
	      if (type == ITEX_DELIMITER_DOLLAR)
1662
		{
1663
		  ptr2++;
1664
		  match = 1;
1665
		}
1666
	      else
1667
		{
1668
		  skip = 1;
1669
		}
1670
	    }
1671
	  break;
1672
1673
	default:
1674
	  break;
1675
	}
1676
      if (skip || match) break;
1677
1678
      ++ptr2;
1679
    }
1680
  if (skip)
1681
    {
1682
      if (type == ITEX_DELIMITER_DOLLAR)
1683
	{
1684
	  if (itex2MML_write)
1685
	    (*itex2MML_write) (ptr1, 1);
1686
	  ptr1++;
1687
	}
1688
      else
1689
	{
1690
	  if (itex2MML_write)
1691
	    (*itex2MML_write) (ptr1, 2);
1692
	  ptr1 += 2;
1693
	}
1694
      goto _until_math;
1695
    }
1696
  if (match)
1697
    {
1698
      mathml = itex2MML_parse (ptr1, ptr2 - ptr1);
1699
1700
      if (mathml)
1701
	{
1702
	  if (itex2MML_write_mathml)
1703
	    (*itex2MML_write_mathml) (mathml);
1704
	  itex2MML_free_string (mathml);
1705
	  mathml = 0;
1706
	}
1707
      else
1708
	{
1709
	  ++result;
1710
	  if (itex2MML_write)
1711
	    {
1712
	      if (type == ITEX_DELIMITER_DOLLAR)
1713
		(*itex2MML_write) ("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><merror><mtext>", 0);
1714
	      else
1715
		(*itex2MML_write) ("<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><merror><mtext>", 0);
1716
1717
	      (*itex2MML_write) (itex2MML_last_error, 0);
1718
	      (*itex2MML_write) ("</mtext></merror></math>", 0);
1719
	    }
1720
	}
1721
      ptr1 = ptr2;
1722
1723
      goto _until_math;
1724
    }
1725
  if (itex2MML_write)
1726
    (*itex2MML_write) (ptr1, ptr2 - ptr1);
1727
1728
 _finish:
1729
  if (itex2MML_last_error)
1730
    {
1731
      itex2MML_free_string (itex2MML_last_error);
1732
      itex2MML_last_error = 0;
1733
    }
1734
  itex2MML_error = save_error_fn;
1735
1736
  return result;
1737
}