/itexToMML

To download this project, use:
bzr branch http://golem.ph.utexas.edu/~distler/code/itexToMML/
49 by Jacques Distler
itex2MML 1.3.24: Fix \hat{} and \widehat{}
1
/*             itex2MML 1.3.24
2
 *   itex2MML.y last modified 5/24/2010
1 by Jacques Distler
Initial commit.
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
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
261
 /* Create a hex character reference string corresponding to code
262
  */
263
 char * itex2MML_character_reference (unsigned long int code)
264
   {
265
#define ENTITY_LENGTH 10
266
     char * entity = (char *) malloc(ENTITY_LENGTH);
40 by Jacques Distler
itex2MML 1.3.16: \tooltip{}{}
267
     sprintf(entity, "&#x%05lx;", code);
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
268
     return entity;
269
   }
270
1 by Jacques Distler
Initial commit.
271
 void itex2MML_free_string (char * str)
272
   {
273
     if (str && str != itex2MML_empty_string)
274
       free(str);
275
   }
276
277
%}
278
21 by Jacques Distler
\binom
279
%left TEXOVER TEXATOP
40 by Jacques Distler
itex2MML 1.3.16: \tooltip{}{}
280
%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 OPERATORNAME MATHOP MATHBIN MATHREL MOP MOL MOLL MOF MOR PERIODDELIM OTHERDELIM LEFTDELIM RIGHTDELIM MOS MOB SQRT ROOT BINOM UNDER OVER OVERBRACE UNDERLINE UNDERBRACE UNDEROVER TENSOR MULTI ARRAY COLSEP ROWSEP ARRAYOPTS COLLAYOUT COLALIGN ROWALIGN ALIGN EQROWS EQCOLS ROWLINES COLLINES FRAME PADDING ATTRLIST ITALICS BOLD SLASHED RM BB ST END BBLOWERCHAR BBUPPERCHAR BBDIGIT CALCHAR FRAKCHAR CAL FRAK CLAP LLAP RLAP ROWOPTS TEXTSIZE SCSIZE SCSCSIZE DISPLAY TEXTSTY TEXTBOX TEXTSTRING XMLSTRING CELLOPTS ROWSPAN COLSPAN THINSPACE MEDSPACE THICKSPACE QUAD QQUAD NEGSPACE PHANTOM HREF UNKNOWNCHAR EMPTYMROW STATLINE TOOLTIP TOGGLE FGHIGHLIGHT BGHIGHLIGHT SPACE INTONE INTTWO INTTHREE BAR WIDEBAR VEC WIDEVEC HAT WIDEHAT CHECK WIDECHECK TILDE WIDETILDE DOT DDOT DDDOT DDDDOT UNARYMINUS UNARYPLUS BEGINENV ENDENV MATRIX PMATRIX BMATRIX BBMATRIX VMATRIX VVMATRIX SVG ENDSVG SMALLMATRIX CASES ALIGNED GATHERED SUBSTACK PMOD RMCHAR COLOR BGCOLOR
1 by Jacques Distler
Initial commit.
281
282
%%
283
284
doc:  xmlmmlTermList {/* all processing done in body*/};
285
286
xmlmmlTermList:
287
{/* nothing - do nothing*/}
288
| char {/* proc done in body*/}
289
| expression {/* all proc. in body*/}
290
| xmlmmlTermList char {/* all proc. in body*/}
291
| xmlmmlTermList expression {/* all proc. in body*/};
292
293
char: CHAR {printf("%s", $1);};
294
295
expression: STARTMATH ENDMATH {/* empty math group - ignore*/}
296
| STARTDMATH ENDMATH {/* ditto */}
297
| STARTMATH compoundTermList ENDMATH {
298
  char ** r = (char **) ret_str;
299
  char * s = itex2MML_copy3("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'>", $2, "</math>");
300
  itex2MML_free_string($2);
301
  if (r) {
302
    (*r) = (s == itex2MML_empty_string) ? 0 : s;
303
  }
304
  else {
305
    if (itex2MML_write_mathml)
306
      (*itex2MML_write_mathml) (s);
307
    itex2MML_free_string(s);
308
  }
309
}
310
| STARTDMATH compoundTermList ENDMATH {
311
  char ** r = (char **) ret_str;
312
  char * s = itex2MML_copy3("<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>", $2, "</math>");
313
  itex2MML_free_string($2);
314
  if (r) {
315
    (*r) = (s == itex2MML_empty_string) ? 0 : s;
316
  }
317
  else {
318
    if (itex2MML_write_mathml)
319
      (*itex2MML_write_mathml) (s);
320
    itex2MML_free_string(s);
321
  }
322
};
323
324
compoundTermList: compoundTerm {
325
  $$ = itex2MML_copy_string($1);
326
  itex2MML_free_string($1);
327
}
328
| compoundTermList compoundTerm {
329
  $$ = itex2MML_copy2($1, $2);
330
  itex2MML_free_string($1);
331
  itex2MML_free_string($2);
332
};
333
334
compoundTerm: mob SUB closedTerm SUP closedTerm {
335
  if (itex2MML_displaymode == 1) {
336
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
337
    char * s2 = itex2MML_copy3($3, " ", $5);
338
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
339
    itex2MML_free_string(s1);
340
    itex2MML_free_string(s2);
341
  }
342
  else {
343
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
344
    char * s2 = itex2MML_copy3($3, " ", $5);
345
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
346
    itex2MML_free_string(s1);
347
    itex2MML_free_string(s2);
348
  }
349
  itex2MML_free_string($1);
350
  itex2MML_free_string($3);
351
  itex2MML_free_string($5);
352
}
353
| mob SUB closedTerm {
354
  if (itex2MML_displaymode == 1) {
355
    char * s1 = itex2MML_copy3("<munder>", $1, " ");
356
    $$ = itex2MML_copy3(s1, $3, "</munder>");
357
    itex2MML_free_string(s1);
358
  }
359
  else {
360
    char * s1 = itex2MML_copy3("<msub>", $1, " ");
361
    $$ = itex2MML_copy3(s1, $3, "</msub>");
362
    itex2MML_free_string(s1);
363
  }
364
  itex2MML_free_string($1);
365
  itex2MML_free_string($3);
366
}
367
| mob SUP closedTerm SUB closedTerm {
368
  if (itex2MML_displaymode == 1) {
369
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
370
    char * s2 = itex2MML_copy3($5, " ", $3);
371
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
372
    itex2MML_free_string(s1);
373
    itex2MML_free_string(s2);
374
  }
375
  else {
376
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
377
    char * s2 = itex2MML_copy3($5, " ", $3);
378
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
379
    itex2MML_free_string(s1);
380
    itex2MML_free_string(s2);
381
  }
382
  itex2MML_free_string($1);
383
  itex2MML_free_string($3);
384
  itex2MML_free_string($5);
385
}
386
| mob SUP closedTerm {
387
  if (itex2MML_displaymode == 1) {
388
    char * s1 = itex2MML_copy3("<mover>", $1, " ");
389
    $$ = itex2MML_copy3(s1, $3, "</mover>");
390
    itex2MML_free_string(s1);
391
  }
392
  else {
393
    char * s1 = itex2MML_copy3("<msup>", $1, " ");
394
    $$ = itex2MML_copy3(s1, $3, "</msup>");
395
    itex2MML_free_string(s1);
396
  }
397
  itex2MML_free_string($1);
398
  itex2MML_free_string($3);
399
}
400
|mib SUB closedTerm SUP closedTerm {
401
  if (itex2MML_displaymode == 1) {
402
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
403
    char * s2 = itex2MML_copy3($3, " ", $5);
404
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
405
    itex2MML_free_string(s1);
406
    itex2MML_free_string(s2);
407
  }
408
  else {
409
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
410
    char * s2 = itex2MML_copy3($3, " ", $5);
411
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
412
    itex2MML_free_string(s1);
413
    itex2MML_free_string(s2);
414
  }
415
  itex2MML_free_string($1);
416
  itex2MML_free_string($3);
417
  itex2MML_free_string($5);
418
}
419
| mib SUB closedTerm {
420
  if (itex2MML_displaymode == 1) {
421
    char * s1 = itex2MML_copy3("<munder>", $1, " ");
422
    $$ = itex2MML_copy3(s1, $3, "</munder>");
423
    itex2MML_free_string(s1);
424
  }
425
  else {
426
    char * s1 = itex2MML_copy3("<msub>", $1, " ");
427
    $$ = itex2MML_copy3(s1, $3, "</msub>");
428
    itex2MML_free_string(s1);
429
  }
430
  itex2MML_free_string($1);
431
  itex2MML_free_string($3);
432
}
433
| mib SUP closedTerm SUB closedTerm {
434
  if (itex2MML_displaymode == 1) {
435
    char * s1 = itex2MML_copy3("<munderover>", $1, " ");
436
    char * s2 = itex2MML_copy3($5, " ", $3);
437
    $$ = itex2MML_copy3(s1, s2, "</munderover>");
438
    itex2MML_free_string(s1);
439
    itex2MML_free_string(s2);
440
  }
441
  else {
442
    char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
443
    char * s2 = itex2MML_copy3($5, " ", $3);
444
    $$ = itex2MML_copy3(s1, s2, "</msubsup>");
445
    itex2MML_free_string(s1);
446
    itex2MML_free_string(s2);
447
  }
448
  itex2MML_free_string($1);
449
  itex2MML_free_string($3);
450
  itex2MML_free_string($5);
451
}
452
| mib SUP closedTerm {
453
  if (itex2MML_displaymode == 1) {
454
    char * s1 = itex2MML_copy3("<mover>", $1, " ");
455
    $$ = itex2MML_copy3(s1, $3, "</mover>");
456
    itex2MML_free_string(s1);
457
  }
458
  else {
459
    char * s1 = itex2MML_copy3("<msup>", $1, " ");
460
    $$ = itex2MML_copy3(s1, $3, "</msup>");
461
    itex2MML_free_string(s1);
462
  }
463
  itex2MML_free_string($1);
464
  itex2MML_free_string($3);
465
}
466
| closedTerm SUB closedTerm SUP closedTerm {
467
  char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
468
  char * s2 = itex2MML_copy3($3, " ", $5);
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 SUP closedTerm SUB closedTerm {
477
  char * s1 = itex2MML_copy3("<msubsup>", $1, " ");
478
  char * s2 = itex2MML_copy3($5, " ", $3);
479
  $$ = itex2MML_copy3(s1, s2, "</msubsup>");
480
  itex2MML_free_string(s1);
481
  itex2MML_free_string(s2);
482
  itex2MML_free_string($1);
483
  itex2MML_free_string($3);
484
  itex2MML_free_string($5);
485
}
486
| closedTerm SUB closedTerm {
487
  char * s1 = itex2MML_copy3("<msub>", $1, " ");
488
  $$ = itex2MML_copy3(s1, $3, "</msub>");
489
  itex2MML_free_string(s1);
490
  itex2MML_free_string($1);
491
  itex2MML_free_string($3);
492
}
493
| closedTerm SUP closedTerm {
494
  char * s1 = itex2MML_copy3("<msup>", $1, " ");
495
  $$ = itex2MML_copy3(s1, $3, "</msup>");
496
  itex2MML_free_string(s1);
497
  itex2MML_free_string($1);
498
  itex2MML_free_string($3);
499
}
500
| SUB closedTerm {
501
  $$ = itex2MML_copy3("<msub><mo></mo>", $2, "</msub>");
502
  itex2MML_free_string($2);
503
}
504
| SUP closedTerm {
505
  $$ = itex2MML_copy3("<msup><mo></mo>", $2, "</msup>");
506
  itex2MML_free_string($2);
507
}
508
| closedTerm {
509
  $$ = itex2MML_copy_string($1);
510
  itex2MML_free_string($1);
511
};
512
513
closedTerm: array
514
| unaryminus
515
| unaryplus
516
| mib
517
| mi {
518
  $$ = itex2MML_copy3("<mi>", $1, "</mi>");
519
  itex2MML_free_string($1);
520
}
521
| mn {
522
  $$ = itex2MML_copy3("<mn>", $1, "</mn>");
523
  itex2MML_free_string($1);
524
}
525
| mo 
526
| tensor
527
| multi
528
| mfrac
529
| binom
530
| msqrt 
531
| mroot
532
| munder
533
| mover
534
| bar
535
| vec
536
| hat
537
| dot
538
| ddot
38 by Jacques Distler
itex2MML 1.3.14: \dddot{} and \ddddot{}
539
| dddot
540
| ddddot
1 by Jacques Distler
Initial commit.
541
| check
542
| tilde
543
| moverbrace
544
| munderbrace
34 by Jacques Distler
itex2MML 1.3.10
545
| munderline
1 by Jacques Distler
Initial commit.
546
| munderover
547
| emptymrow
37 by Jacques Distler
itex2MML 1.3.13
548
| mathclap
549
| mathllap
550
| mathrlap
1 by Jacques Distler
Initial commit.
551
| displaystyle
552
| textstyle
553
| textsize
554
| scriptsize
555
| scriptscriptsize
556
| italics
557
| bold
558
| roman
559
| rmchars
560
| bbold
561
| frak
16 by Jacques Distler
Slashed letters
562
| slashed
1 by Jacques Distler
Initial commit.
563
| cal
564
| space
565
| textstring
566
| thinspace
567
| medspace
568
| thickspace
569
| quad
570
| qquad
571
| negspace
572
| phantom
573
| href
574
| statusline
40 by Jacques Distler
itex2MML 1.3.16: \tooltip{}{}
575
| tooltip
1 by Jacques Distler
Initial commit.
576
| toggle
577
| fghighlight
578
| bghighlight
579
| color
580
| texover
21 by Jacques Distler
\binom
581
| texatop
1 by Jacques Distler
Initial commit.
582
| MROWOPEN closedTerm MROWCLOSE {
583
  $$ = itex2MML_copy_string($2);
584
  itex2MML_free_string($2);
585
}
586
| MROWOPEN compoundTermList MROWCLOSE {
587
  $$ = itex2MML_copy3("<mrow>", $2, "</mrow>");
588
  itex2MML_free_string($2);
589
}
590
| left compoundTermList right {
591
  char * s1 = itex2MML_copy3("<mrow>", $1, $2);
592
  $$ = itex2MML_copy3(s1, $3, "</mrow>");
593
  itex2MML_free_string(s1);
594
  itex2MML_free_string($1);
595
  itex2MML_free_string($2);
596
  itex2MML_free_string($3);
597
}
598
| mathenv
599
| substack
600
| pmod
601
| unrecognized;
602
603
left: LEFT LEFTDELIM {
604
  itex2MML_rowposn = 2;
605
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
606
  itex2MML_free_string($2);
607
}
608
| LEFT OTHERDELIM {
609
  itex2MML_rowposn = 2;
610
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
611
  itex2MML_free_string($2);
612
}
613
| LEFT PERIODDELIM {
614
  itex2MML_rowposn = 2;
615
  $$ = itex2MML_copy_string("");
616
  itex2MML_free_string($2);
617
};
618
619
right: RIGHT RIGHTDELIM {
620
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
621
  itex2MML_free_string($2);
622
}
623
| RIGHT OTHERDELIM {
624
  $$ = itex2MML_copy3("<mo>", $2, "</mo>");
625
  itex2MML_free_string($2);
626
}
627
| RIGHT PERIODDELIM {
628
  $$ = itex2MML_copy_string("");
629
  itex2MML_free_string($2);
630
};
631
632
bigdelim: BIG LEFTDELIM {
633
  itex2MML_rowposn = 2;
634
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
635
  itex2MML_free_string($2);
636
} 
637
| BIG RIGHTDELIM {
638
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
639
  itex2MML_free_string($2);
640
}
641
| BIG OTHERDELIM {
642
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
643
  itex2MML_free_string($2);
644
}
645
| BBIG LEFTDELIM {
646
  itex2MML_rowposn = 2;
647
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
648
  itex2MML_free_string($2);
649
}
650
| BBIG RIGHTDELIM {
651
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
652
  itex2MML_free_string($2);
653
}
654
| BBIG OTHERDELIM {
655
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
656
  itex2MML_free_string($2);
657
}
658
| BIGG LEFTDELIM {
659
  itex2MML_rowposn = 2;
660
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
661
  itex2MML_free_string($2);
662
} 
663
| BIGG RIGHTDELIM {
664
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
665
  itex2MML_free_string($2);
666
}
667
| BIGG OTHERDELIM {
668
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
669
  itex2MML_free_string($2);
670
}
671
| BBIGG LEFTDELIM {
672
  itex2MML_rowposn = 2;
673
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
674
  itex2MML_free_string($2);
675
}
676
| BBIGG RIGHTDELIM {
677
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
678
  itex2MML_free_string($2);
679
}
680
| BBIGG OTHERDELIM {
681
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
682
  itex2MML_free_string($2);
683
}
22 by Jacques Distler
SVG Environment
684
|BIGL LEFTDELIM {
1 by Jacques Distler
Initial commit.
685
  itex2MML_rowposn = 2;
686
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
687
  itex2MML_free_string($2);
688
}
689
| BIGL OTHERDELIM {
690
  itex2MML_rowposn = 2;
691
  $$ = itex2MML_copy3("<mo maxsize=\"1.2em\" minsize=\"1.2em\">", $2, "</mo>");
692
  itex2MML_free_string($2);
693
}
694
| BBIGL LEFTDELIM {
695
  itex2MML_rowposn = 2;
696
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
697
  itex2MML_free_string($2);
698
}
699
| BBIGL OTHERDELIM {
700
  itex2MML_rowposn = 2;
701
  $$ = itex2MML_copy3("<mo maxsize=\"1.8em\" minsize=\"1.8em\">", $2, "</mo>");
702
  itex2MML_free_string($2);
703
}
704
| BIGGL LEFTDELIM {
705
  itex2MML_rowposn = 2;
706
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
707
  itex2MML_free_string($2);
708
} 
709
| BIGGL OTHERDELIM {
710
  itex2MML_rowposn = 2;
711
  $$ = itex2MML_copy3("<mo maxsize=\"2.4em\" minsize=\"2.4em\">", $2, "</mo>");
712
  itex2MML_free_string($2);
713
}
714
| BBIGGL LEFTDELIM {
715
  itex2MML_rowposn = 2;
716
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
717
  itex2MML_free_string($2);
718
}
719
| BBIGGL OTHERDELIM {
720
  itex2MML_rowposn = 2;
721
  $$ = itex2MML_copy3("<mo maxsize=\"3em\" minsize=\"3em\">", $2, "</mo>");
722
  itex2MML_free_string($2);
723
};
724
725
unrecognized: UNKNOWNCHAR {
726
  $$ = itex2MML_copy_string("<merror><mtext>Unknown character</mtext></merror>");
727
};
728
729
unaryminus: UNARYMINUS {
730
  $$ = itex2MML_copy_string("<mo lspace=\"verythinmathspace\" rspace=\"0em\">&minus;</mo>");
731
};
732
733
unaryplus: UNARYPLUS {
734
  $$ = itex2MML_copy_string("<mo lspace=\"verythinmathspace\" rspace=\"0em\">+</mo>");
735
};
736
737
mi: MI;
738
739
mib: MIB {
740
  itex2MML_rowposn=2;
741
  $$ = itex2MML_copy3("<mi>", $1, "</mi>");
742
  itex2MML_free_string($1);
743
};
744
745
mn: MN;
746
747
mob: MOB {
748
  itex2MML_rowposn = 2;
749
  $$ = itex2MML_copy3("<mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">", $1, "</mo>");
750
  itex2MML_free_string($1);
751
};
752
753
mo: mob
754
| bigdelim
755
| MO {
756
  itex2MML_rowposn = 2;
757
  $$ = itex2MML_copy3("<mo>", $1, "</mo>");
758
  itex2MML_free_string($1);
759
}
760
| MOL {
761
  itex2MML_rowposn = 2;
762
  $$ = itex2MML_copy3("<mo>", $1, "</mo>");
763
  itex2MML_free_string($1);
764
}
18 by Jacques Distler
Minor Tweaks
765
| MOLL {
766
  itex2MML_rowposn = 2;
767
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"0\"><mo>", $1, "</mo></mstyle>");
768
  itex2MML_free_string($1);
769
}
1 by Jacques Distler
Initial commit.
770
| RIGHTDELIM {
771
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
772
  itex2MML_free_string($1);
773
}
774
| LEFTDELIM {
775
  itex2MML_rowposn = 2;
776
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
777
  itex2MML_free_string($1);
778
}
779
| OTHERDELIM {
780
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
781
  itex2MML_free_string($1);
782
}
783
| MOF {
784
  $$ = itex2MML_copy3("<mo stretchy=\"false\">", $1, "</mo>");
785
  itex2MML_free_string($1);
786
}
787
| PERIODDELIM {
788
  $$ = itex2MML_copy3("<mo>", $1, "</mo>");
789
  itex2MML_free_string($1);
790
}
791
| MOS {
792
  itex2MML_rowposn=2;
793
  $$ = itex2MML_copy3("<mo lspace=\"mediummathspace\" rspace=\"mediummathspace\">", $1, "</mo>");
794
  itex2MML_free_string($1);
795
}
796
| MOP {
797
  itex2MML_rowposn = 2;
798
  $$ = itex2MML_copy3("<mo lspace=\"0em\" rspace=\"thinmathspace\">", $1, "</mo>");
799
  itex2MML_free_string($1);
800
}
37 by Jacques Distler
itex2MML 1.3.13
801
| MOR {
802
  itex2MML_rowposn = 2;
803
  $$ = itex2MML_copy3("<mo lspace=\"verythinmathspace\">", $1, "</mo>");
804
  itex2MML_free_string($1);
805
}
39 by Jacques Distler
itex2MML 1.3.15: \mathrel and its cousins
806
| OPERATORNAME TEXTSTRING {
807
  itex2MML_rowposn = 2;
808
  $$ = itex2MML_copy3("<mo lspace=\"0em\" rspace=\"thinmathspace\">", $2, "</mo>");
809
  itex2MML_free_string($2);
810
}
1 by Jacques Distler
Initial commit.
811
| MATHOP TEXTSTRING {
812
  itex2MML_rowposn = 2;
39 by Jacques Distler
itex2MML 1.3.15: \mathrel and its cousins
813
  $$ = itex2MML_copy3("<mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">", $2, "</mo>");
814
  itex2MML_free_string($2);
815
}
816
| MATHBIN TEXTSTRING {
817
  itex2MML_rowposn = 2;
818
  $$ = itex2MML_copy3("<mo lspace=\"mediummathspace\" rspace=\"mediummathspace\">", $2, "</mo>");
819
  itex2MML_free_string($2);
820
}
821
| MATHREL TEXTSTRING {
822
  itex2MML_rowposn = 2;
823
  $$ = itex2MML_copy3("<mo lspace=\"thickmathspace\" rspace=\"thickmathspace\">", $2, "</mo>");
1 by Jacques Distler
Initial commit.
824
  itex2MML_free_string($2);
825
};
826
827
emptymrow: EMPTYMROW {
828
  $$ = itex2MML_copy_string("<mrow></mrow>");
829
};
830
831
space: SPACE ST INTONE END ST INTTWO END ST INTTHREE END {
832
  char * s1 = itex2MML_copy3("<mspace height=\"", $3, "ex\" depth=\"");
833
  char * s2 = itex2MML_copy3($6, "ex\" width=\"", $9);
834
  $$ = itex2MML_copy3(s1, s2, "em\"></mspace>");
835
  itex2MML_free_string(s1);
836
  itex2MML_free_string(s2);
837
  itex2MML_free_string($3);
838
  itex2MML_free_string($6);
839
  itex2MML_free_string($9);
840
};
841
842
statusline: STATLINE TEXTSTRING closedTerm {
843
  char * s1 = itex2MML_copy3("<maction actiontype=\"statusline\">", $3, "<mtext>");
844
  $$ = itex2MML_copy3(s1, $2, "</mtext></maction>");
845
  itex2MML_free_string(s1);
846
  itex2MML_free_string($2);
847
  itex2MML_free_string($3);
848
};
849
40 by Jacques Distler
itex2MML 1.3.16: \tooltip{}{}
850
tooltip: TOOLTIP TEXTSTRING closedTerm {
851
  char * s1 = itex2MML_copy3("<maction actiontype=\"tooltip\">", $3, "<mtext>");
852
  $$ = itex2MML_copy3(s1, $2, "</mtext></maction>");
853
  itex2MML_free_string(s1);
854
  itex2MML_free_string($2);
855
  itex2MML_free_string($3);
856
};
857
1 by Jacques Distler
Initial commit.
858
toggle: TOGGLE closedTerm closedTerm {
859
  char * s1 = itex2MML_copy3("<maction actiontype=\"toggle\" selection=\"2\">", $2, " ");
860
  $$ = itex2MML_copy3(s1, $3, "</maction>");
861
  itex2MML_free_string(s1);
862
  itex2MML_free_string($2);
863
  itex2MML_free_string($3);
864
};
865
866
fghighlight: FGHIGHLIGHT ATTRLIST closedTerm {
867
  char * s1 = itex2MML_copy3("<maction actiontype=\"highlight\" other='color=", $2, "'>");
868
  $$ = itex2MML_copy3(s1, $3, "</maction>");
869
  itex2MML_free_string(s1);
870
  itex2MML_free_string($2);
871
  itex2MML_free_string($3);
872
};
873
874
bghighlight: BGHIGHLIGHT ATTRLIST closedTerm {
875
  char * s1 = itex2MML_copy3("<maction actiontype=\"highlight\" other='background=", $2, "'>");
876
  $$ = itex2MML_copy3(s1, $3, "</maction>");
877
  itex2MML_free_string(s1);
878
  itex2MML_free_string($2);
879
  itex2MML_free_string($3);
880
};
881
882
color: COLOR ATTRLIST compoundTermList {
883
  char * s1 = itex2MML_copy3("<mstyle mathcolor=", $2, ">");
884
  $$ = itex2MML_copy3(s1, $3, "</mstyle>");
885
  itex2MML_free_string(s1);
886
  itex2MML_free_string($2);
887
  itex2MML_free_string($3);
888
}
889
| BGCOLOR ATTRLIST compoundTermList {
890
  char * s1 = itex2MML_copy3("<mstyle mathbackground=", $2, ">");
891
  $$ = itex2MML_copy3(s1, $3, "</mstyle>");
892
  itex2MML_free_string(s1);
893
  itex2MML_free_string($2);
894
  itex2MML_free_string($3);
895
};
896
37 by Jacques Distler
itex2MML 1.3.13
897
mathrlap: RLAP closedTerm {
33 by Jacques Distler
itex2MML 1.3.9: implement \rlap
898
  $$ = itex2MML_copy3("<mpadded width=\"0\">", $2, "</mpadded>");
899
  itex2MML_free_string($2);
900
};
901
37 by Jacques Distler
itex2MML 1.3.13
902
mathllap: LLAP closedTerm {
903
  $$ = itex2MML_copy3("<mpadded width=\"0\" lspace=\"-100%width\">", $2, "</mpadded>");
904
  itex2MML_free_string($2);
905
};
906
907
mathclap: CLAP closedTerm {
908
  $$ = itex2MML_copy3("<mpadded width=\"0\" lspace=\"-50%width\">", $2, "</mpadded>");
909
  itex2MML_free_string($2);
910
};
911
1 by Jacques Distler
Initial commit.
912
textstring: TEXTBOX TEXTSTRING {
913
  $$ = itex2MML_copy3("<mtext>", $2, "</mtext>");
914
  itex2MML_free_string($2);
915
};
916
917
displaystyle: DISPLAY closedTerm {
918
  $$ = itex2MML_copy3("<mstyle displaystyle=\"true\">", $2, "</mstyle>");
919
  itex2MML_free_string($2);
920
};
921
922
textstyle: TEXTSTY closedTerm {
923
  $$ = itex2MML_copy3("<mstyle displaystyle=\"false\">", $2, "</mstyle>");
924
  itex2MML_free_string($2);
925
};
926
927
textsize: TEXTSIZE closedTerm {
928
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"0\">", $2, "</mstyle>");
929
  itex2MML_free_string($2);
930
};
931
932
scriptsize: SCSIZE closedTerm {
933
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"1\">", $2, "</mstyle>");
934
  itex2MML_free_string($2);
935
};
936
937
scriptscriptsize: SCSCSIZE closedTerm {
938
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"2\">", $2, "</mstyle>");
939
  itex2MML_free_string($2);
940
};
941
942
italics: ITALICS closedTerm {
943
  $$ = itex2MML_copy3("<mstyle mathvariant=\"italic\">", $2, "</mstyle>");
944
  itex2MML_free_string($2);
945
};
946
16 by Jacques Distler
Slashed letters
947
slashed: SLASHED closedTerm {
948
  $$ = itex2MML_copy3("<mrow><mpadded width=\"0.125em\"><mo>&#xff0f;</mo></mpadded>", $2, "</mrow>");
949
  itex2MML_free_string($2);
950
};
951
1 by Jacques Distler
Initial commit.
952
bold: BOLD closedTerm {
953
  $$ = itex2MML_copy3("<mstyle mathvariant=\"bold\">", $2, "</mstyle>");
954
  itex2MML_free_string($2);
955
};
956
957
roman: RM ST rmchars END {
958
  $$ = itex2MML_copy3("<mi mathvariant=\"normal\">", $3, "</mi>");
959
  itex2MML_free_string($3);
960
};
961
962
rmchars: RMCHAR {
963
  $$ = itex2MML_copy_string($1);
964
  itex2MML_free_string($1);
965
}
966
| rmchars RMCHAR {
967
  $$ = itex2MML_copy2($1, $2);
968
  itex2MML_free_string($1);
969
  itex2MML_free_string($2);
970
};
971
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
972
bbold: BB ST bbchars END {
1 by Jacques Distler
Initial commit.
973
  $$ = itex2MML_copy3("<mi>", $3, "</mi>");
974
  itex2MML_free_string($3);
975
};
976
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
977
bbchars: bbchar {
1 by Jacques Distler
Initial commit.
978
  $$ = itex2MML_copy_string($1);
979
  itex2MML_free_string($1);
980
}
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
981
| bbchars bbchar {
1 by Jacques Distler
Initial commit.
982
  $$ = itex2MML_copy2($1, $2);
983
  itex2MML_free_string($1);
984
  itex2MML_free_string($2);
985
};
986
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
987
bbchar: BBLOWERCHAR {
26 by Jacques Distler
Lowercase Blackboard Bold Letters
988
  $$ = itex2MML_copy3("&", $1, "opf;");
1 by Jacques Distler
Initial commit.
989
  itex2MML_free_string($1);
990
}
991
| BBUPPERCHAR {
992
  $$ = itex2MML_copy3("&", $1, "opf;");
993
  itex2MML_free_string($1);
32 by Jacques Distler
itex2MML 1.38: Support for Blackboard Bold Digits
994
}
995
| BBDIGIT {
996
  /* Blackboard digits 0-9 correspond to Unicode characters 0x1D7D8-0x1D7E1 */
997
  char * end = $1 + 1;
998
  int code = 0x1D7D8 + strtoul($1, &end, 10);
999
  $$ = itex2MML_character_reference(code);
1000
  itex2MML_free_string($1);
1 by Jacques Distler
Initial commit.
1001
};
1002
1003
frak: FRAK ST frakletters END {
1004
  $$ = itex2MML_copy3("<mi>", $3, "</mi>");
1005
  itex2MML_free_string($3);
1006
};
1007
1008
frakletters: frakletter {
1009
  $$ = itex2MML_copy_string($1);
1010
  itex2MML_free_string($1);
1011
}
1012
| frakletters frakletter {
1013
  $$ = itex2MML_copy2($1, $2);
1014
  itex2MML_free_string($1);
1015
  itex2MML_free_string($2);
1016
};
1017
1018
frakletter: FRAKCHAR {
1019
  $$ = itex2MML_copy3("&", $1, "fr;");
1020
  itex2MML_free_string($1);
1021
};
1022
1023
cal: CAL ST calletters END {
1024
  $$ = itex2MML_copy3("<mi>", $3, "</mi>");
1025
  itex2MML_free_string($3);
1026
};
1027
1028
calletters: calletter {
1029
  $$ = itex2MML_copy_string($1);
1030
  itex2MML_free_string($1);
1031
}
1032
| calletters calletter {
1033
  $$ = itex2MML_copy2($1, $2);
1034
  itex2MML_free_string($1);
1035
  itex2MML_free_string($2);
1036
};
1037
1038
calletter: CALCHAR {
1039
  $$ = itex2MML_copy3("&", $1, "scr;");
1040
  itex2MML_free_string($1);
1041
};
1042
1043
thinspace: THINSPACE {
1044
  $$ = itex2MML_copy_string("<mspace width=\"thinmathspace\"></mspace>");
1045
};
1046
1047
medspace: MEDSPACE {
1048
  $$ = itex2MML_copy_string("<mspace width=\"mediummathspace\"></mspace>");
1049
};
1050
1051
thickspace: THICKSPACE {
1052
  $$ = itex2MML_copy_string("<mspace width=\"thickmathspace\"></mspace>");
1053
};
1054
1055
quad: QUAD {
1056
  $$ = itex2MML_copy_string("<mspace width=\"1em\"></mspace>");
1057
};
1058
1059
qquad: QQUAD {
1060
  $$ = itex2MML_copy_string("<mspace width=\"2em\"></mspace>");
1061
};
1062
1063
negspace: NEGSPACE {
1064
  $$ = itex2MML_copy_string("<mspace width=\"-0.1667 em\"></mspace>");
1065
};
1066
1067
phantom: PHANTOM closedTerm {
1068
  $$ = itex2MML_copy3("<mphantom>", $2, "</mphantom>");
1069
  itex2MML_free_string($2);
1070
};
1071
1072
href: HREF TEXTSTRING closedTerm {
1073
  char * s1 = itex2MML_copy3("<mrow xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"", $2, "\">");
1074
  $$ = itex2MML_copy3(s1, $3, "</mrow>");
1075
  itex2MML_free_string(s1);
1076
  itex2MML_free_string($2);
1077
  itex2MML_free_string($3);
1078
};
1079
1080
tensor: TENSOR closedTerm MROWOPEN subsupList MROWCLOSE {
1081
  char * s1 = itex2MML_copy3("<mmultiscripts>", $2, $4);
1082
  $$ = itex2MML_copy2(s1, "</mmultiscripts>");
1083
  itex2MML_free_string(s1);
1084
  itex2MML_free_string($2);
1085
  itex2MML_free_string($4);
1086
}
1087
| TENSOR closedTerm subsupList {
1088
  char * s1 = itex2MML_copy3("<mmultiscripts>", $2, $3);
1089
  $$ = itex2MML_copy2(s1, "</mmultiscripts>");
1090
  itex2MML_free_string(s1);
1091
  itex2MML_free_string($2);
1092
  itex2MML_free_string($3);
1093
};
1094
1095
multi: MULTI MROWOPEN subsupList MROWCLOSE closedTerm MROWOPEN subsupList MROWCLOSE {
1096
  char * s1 = itex2MML_copy3("<mmultiscripts>", $5, $7);
1097
  char * s2 = itex2MML_copy3("<mprescripts></mprescripts>", $3, "</mmultiscripts>");
1098
  $$ = itex2MML_copy2(s1, s2);
1099
  itex2MML_free_string(s1);
1100
  itex2MML_free_string(s2);
1101
  itex2MML_free_string($3);
1102
  itex2MML_free_string($5);
1103
  itex2MML_free_string($7);
1104
}
1105
| MULTI MROWOPEN subsupList MROWCLOSE closedTerm EMPTYMROW {
1106
  char * s1 = itex2MML_copy2("<mmultiscripts>", $5);
1107
  char * s2 = itex2MML_copy3("<mprescripts></mprescripts>", $3, "</mmultiscripts>");
1108
  $$ = itex2MML_copy2(s1, s2);
1109
  itex2MML_free_string(s1);
1110
  itex2MML_free_string(s2);
1111
  itex2MML_free_string($3);
1112
  itex2MML_free_string($5);
1113
}
1114
| MULTI EMPTYMROW closedTerm MROWOPEN subsupList MROWCLOSE {
1115
  char * s1 = itex2MML_copy3("<mmultiscripts>", $3, $5);
1116
  $$ = itex2MML_copy2(s1, "</mmultiscripts>");
1117
  itex2MML_free_string(s1);
1118
  itex2MML_free_string($3);
1119
  itex2MML_free_string($5); 
1120
};
1121
1122
subsupList: subsupTerm {
1123
  $$ = itex2MML_copy_string($1);
1124
  itex2MML_free_string($1);
1125
}
1126
| subsupList subsupTerm {
1127
  $$ = itex2MML_copy3($1, " ", $2);
1128
  itex2MML_free_string($1);
1129
  itex2MML_free_string($2);
1130
};
1131
1132
subsupTerm: SUB closedTerm SUP closedTerm {
1133
  $$ = itex2MML_copy3($2, " ", $4);
1134
  itex2MML_free_string($2);
1135
  itex2MML_free_string($4);
1136
}
1137
| SUB closedTerm {
1138
  $$ = itex2MML_copy2($2, " <none></none>");
1139
  itex2MML_free_string($2);
1140
}
1141
| SUP closedTerm {
1142
  $$ = itex2MML_copy2("<none></none> ", $2);
1143
  itex2MML_free_string($2);
1144
}
1145
| SUB SUP closedTerm {
1146
  $$ = itex2MML_copy2("<none></none> ", $3);
1147
  itex2MML_free_string($3);
1148
};
1149
1150
mfrac: FRAC closedTerm closedTerm {
1151
  char * s1 = itex2MML_copy3("<mfrac>", $2, $3);
1152
  $$ = itex2MML_copy2(s1, "</mfrac>");
1153
  itex2MML_free_string(s1);
1154
  itex2MML_free_string($2);
1155
  itex2MML_free_string($3);
1156
}
1157
| TFRAC closedTerm closedTerm {
1158
  char * s1 = itex2MML_copy3("<mstyle displaystyle=\"false\"><mfrac>", $2, $3);
1159
  $$ = itex2MML_copy2(s1, "</mfrac></mstyle>");
1160
  itex2MML_free_string(s1);
1161
  itex2MML_free_string($2);
1162
  itex2MML_free_string($3);
1163
};
1164
1165
pmod: PMOD closedTerm {
1166
  $$ = itex2MML_copy3( "<mo lspace=\"mediummathspace\">(</mo><mo rspace=\"thinmathspace\">mod</mo>", $2, "<mo rspace=\"mediummathspace\">)</mo>");
1167
  itex2MML_free_string($2);
1168
}
1169
1170
texover: MROWOPEN compoundTermList TEXOVER compoundTermList MROWCLOSE {
1171
  char * s1 = itex2MML_copy3("<mfrac><mrow>", $2, "</mrow><mrow>");
1172
  $$ = itex2MML_copy3(s1, $4, "</mrow></mfrac>");
1173
  itex2MML_free_string(s1);
1174
  itex2MML_free_string($2);
1175
  itex2MML_free_string($4);
1176
}
1177
| left compoundTermList TEXOVER compoundTermList right {
1178
  char * s1 = itex2MML_copy3("<mrow>", $1, "<mfrac><mrow>");
1179
  char * s2 = itex2MML_copy3($2, "</mrow><mrow>", $4);
1180
  char * s3 = itex2MML_copy3("</mrow></mfrac>", $5, "</mrow>");
1181
  $$ = itex2MML_copy3(s1, s2, s3);
1182
  itex2MML_free_string(s1);
1183
  itex2MML_free_string(s2);
1184
  itex2MML_free_string(s3);
1185
  itex2MML_free_string($1);
1186
  itex2MML_free_string($2);
1187
  itex2MML_free_string($4);
1188
  itex2MML_free_string($5);
1189
};
1190
21 by Jacques Distler
\binom
1191
texatop: MROWOPEN compoundTermList TEXATOP compoundTermList MROWCLOSE {
1192
  char * s1 = itex2MML_copy3("<mfrac linethickness=\"0\"><mrow>", $2, "</mrow><mrow>");
1193
  $$ = itex2MML_copy3(s1, $4, "</mrow></mfrac>");
1194
  itex2MML_free_string(s1);
1195
  itex2MML_free_string($2);
1196
  itex2MML_free_string($4);
1197
}
1198
| left compoundTermList TEXATOP compoundTermList right {
1199
  char * s1 = itex2MML_copy3("<mrow>", $1, "<mfrac linethickness=\"0\"><mrow>");
1200
  char * s2 = itex2MML_copy3($2, "</mrow><mrow>", $4);
1201
  char * s3 = itex2MML_copy3("</mrow></mfrac>", $5, "</mrow>");
1202
  $$ = itex2MML_copy3(s1, s2, s3);
1203
  itex2MML_free_string(s1);
1204
  itex2MML_free_string(s2);
1205
  itex2MML_free_string(s3);
1206
  itex2MML_free_string($1);
1207
  itex2MML_free_string($2);
1208
  itex2MML_free_string($4);
1209
  itex2MML_free_string($5);
1210
};
1211
1 by Jacques Distler
Initial commit.
1212
binom: BINOM closedTerm closedTerm {
21 by Jacques Distler
\binom
1213
  char * s1 = itex2MML_copy3("<mrow><mo>(</mo><mfrac linethickness=\"0\">", $2, $3);
1214
  $$ = itex2MML_copy2(s1, "</mfrac><mo>)</mo></mrow>");
1 by Jacques Distler
Initial commit.
1215
  itex2MML_free_string(s1);
1216
  itex2MML_free_string($2);
1217
  itex2MML_free_string($3);
1218
};
1219
1220
munderbrace: UNDERBRACE closedTerm {
1221
  $$ = itex2MML_copy3("<munder>", $2, "<mo>&UnderBrace;</mo></munder>");
1222
  itex2MML_free_string($2);
1223
};
1224
34 by Jacques Distler
itex2MML 1.3.10
1225
munderline: UNDERLINE closedTerm {
42 by Jacques Distler
itex2MML 1.3.18
1226
  $$ = itex2MML_copy3("<munder>", $2, "<mo>&#x00332;</mo></munder>");
34 by Jacques Distler
itex2MML 1.3.10
1227
  itex2MML_free_string($2);
1228
};
1229
1 by Jacques Distler
Initial commit.
1230
moverbrace: OVERBRACE closedTerm {
1231
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&OverBrace;</mo></mover>");
1232
  itex2MML_free_string($2);
1233
};
1234
1235
bar: BAR closedTerm {
42 by Jacques Distler
itex2MML 1.3.18
1236
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&#x000AF;</mo></mover>");
1 by Jacques Distler
Initial commit.
1237
  itex2MML_free_string($2);
1238
}
1239
| WIDEBAR closedTerm {
42 by Jacques Distler
itex2MML 1.3.18
1240
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&#x000AF;</mo></mover>");
1 by Jacques Distler
Initial commit.
1241
  itex2MML_free_string($2);
1242
};
1243
1244
vec: VEC closedTerm {
1245
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&RightVector;</mo></mover>");
1246
  itex2MML_free_string($2);
1247
}
1248
| WIDEVEC closedTerm {
1249
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&RightVector;</mo></mover>");
1250
  itex2MML_free_string($2);
1251
};
1252
1253
dot: DOT closedTerm {
1254
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&dot;</mo></mover>");
1255
  itex2MML_free_string($2);
1256
};
1257
1258
ddot: DDOT closedTerm {
1259
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&Dot;</mo></mover>");
1260
  itex2MML_free_string($2);
1261
};
1262
38 by Jacques Distler
itex2MML 1.3.14: \dddot{} and \ddddot{}
1263
dddot: DDDOT closedTerm {
1264
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&tdot;</mo></mover>");
1265
  itex2MML_free_string($2);
1266
};
1267
1268
ddddot: DDDDOT closedTerm {
1269
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&DotDot;</mo></mover>");
1270
  itex2MML_free_string($2);
1271
};
1272
1 by Jacques Distler
Initial commit.
1273
tilde: TILDE closedTerm {
1274
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&tilde;</mo></mover>");
1275
  itex2MML_free_string($2);
1276
}
1277
| WIDETILDE closedTerm {
1278
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&tilde;</mo></mover>");
1279
  itex2MML_free_string($2);
1280
};
1281
1282
check: CHECK closedTerm {
18 by Jacques Distler
Minor Tweaks
1283
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&#x2c7;</mo></mover>");
1 by Jacques Distler
Initial commit.
1284
  itex2MML_free_string($2);
1285
}
1286
| WIDECHECK closedTerm {
18 by Jacques Distler
Minor Tweaks
1287
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&#x2c7;</mo></mover>");
1 by Jacques Distler
Initial commit.
1288
  itex2MML_free_string($2);
1289
};
1290
1291
hat: HAT closedTerm {
49 by Jacques Distler
itex2MML 1.3.24: Fix \hat{} and \widehat{}
1292
  $$ = itex2MML_copy3("<mover>", $2, "<mo stretchy=\"false\">&#x5E;</mo></mover>");
1 by Jacques Distler
Initial commit.
1293
  itex2MML_free_string($2);
1294
}
1295
| WIDEHAT closedTerm {
49 by Jacques Distler
itex2MML 1.3.24: Fix \hat{} and \widehat{}
1296
  $$ = itex2MML_copy3("<mover>", $2, "<mo>&#x5E;</mo></mover>");
1 by Jacques Distler
Initial commit.
1297
  itex2MML_free_string($2);
1298
};
1299
1300
msqrt: SQRT closedTerm {
1301
  $$ = itex2MML_copy3("<msqrt>", $2, "</msqrt>");
1302
  itex2MML_free_string($2);
1303
};
1304
1305
mroot: ROOT closedTerm closedTerm {
1306
  char * s1 = itex2MML_copy3("<mroot>", $3, $2);
1307
  $$ = itex2MML_copy2(s1, "</mroot>");
1308
  itex2MML_free_string(s1);
1309
  itex2MML_free_string($2);
1310
  itex2MML_free_string($3);
1311
};
1312
1313
munder: UNDER closedTerm closedTerm {
1314
  char * s1 = itex2MML_copy3("<munder>", $3, $2);
1315
  $$ = itex2MML_copy2(s1, "</munder>");
1316
  itex2MML_free_string(s1);
1317
  itex2MML_free_string($2);
1318
  itex2MML_free_string($3);
1319
};
1320
1321
mover: OVER closedTerm closedTerm {
1322
  char * s1 = itex2MML_copy3("<mover>", $3, $2);
1323
  $$ = itex2MML_copy2(s1, "</mover>");
1324
  itex2MML_free_string(s1);
1325
  itex2MML_free_string($2);
1326
  itex2MML_free_string($3);
1327
};
1328
1329
munderover: UNDEROVER closedTerm closedTerm closedTerm {
1330
  char * s1 = itex2MML_copy3("<munderover>", $4, $2);
1331
  $$ = itex2MML_copy3(s1, $3, "</munderover>");
1332
  itex2MML_free_string(s1);
1333
  itex2MML_free_string($2);
1334
  itex2MML_free_string($3);
1335
  itex2MML_free_string($4);
1336
};
1337
1338
mathenv: BEGINENV MATRIX tableRowList ENDENV MATRIX {
1339
  $$ = itex2MML_copy3("<mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow>");
1340
  itex2MML_free_string($3);
1341
}
8 by Jacques Distler
itex2MML 1.1.9;
1342
|  BEGINENV GATHERED tableRowList ENDENV GATHERED {
1343
  $$ = itex2MML_copy3("<mrow><mtable rowspacing=\"1.0ex\">", $3, "</mtable></mrow>");
1344
  itex2MML_free_string($3);
1345
}
1 by Jacques Distler
Initial commit.
1346
| BEGINENV PMATRIX tableRowList ENDENV PMATRIX {
1347
  $$ = itex2MML_copy3("<mrow><mo>(</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>)</mo></mrow>");
1348
  itex2MML_free_string($3);
1349
}
1350
| BEGINENV BMATRIX tableRowList ENDENV BMATRIX {
1351
  $$ = itex2MML_copy3("<mrow><mo>[</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>]</mo></mrow>");
1352
  itex2MML_free_string($3);
1353
}
1354
| BEGINENV VMATRIX tableRowList ENDENV VMATRIX {
1355
  $$ = itex2MML_copy3("<mrow><mo>&VerticalBar;</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>&VerticalBar;</mo></mrow>");
1356
  itex2MML_free_string($3);
1357
}
1358
| BEGINENV BBMATRIX tableRowList ENDENV BBMATRIX {
1359
  $$ = itex2MML_copy3("<mrow><mo>{</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>}</mo></mrow>");
1360
  itex2MML_free_string($3);
1361
}
1362
| BEGINENV VVMATRIX tableRowList ENDENV VVMATRIX {
1363
  $$ = itex2MML_copy3("<mrow><mo>&DoubleVerticalBar;</mo><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow><mo>&DoubleVerticalBar;</mo></mrow>");
1364
  itex2MML_free_string($3);
1365
}
1366
| BEGINENV SMALLMATRIX tableRowList ENDENV SMALLMATRIX {
1367
  $$ = itex2MML_copy3("<mstyle scriptlevel=\"2\"><mrow><mtable rowspacing=\"0.5ex\">", $3, "</mtable></mrow></mstyle>");
1368
  itex2MML_free_string($3);
1369
}
1370
| BEGINENV CASES tableRowList ENDENV CASES {
1371
  $$ = itex2MML_copy3("<mrow><mo>{</mo><mrow><mtable columnalign=\"left left\">", $3, "</mtable></mrow></mrow>");
1372
  itex2MML_free_string($3);
1373
}
1374
| BEGINENV ALIGNED tableRowList ENDENV ALIGNED {
8 by Jacques Distler
itex2MML 1.1.9;
1375
  $$ = itex2MML_copy3("<mrow><mtable columnalign=\"right left right left right left right left right left\" columnspacing=\"0em\">", $3, "</mtable></mrow>");
1 by Jacques Distler
Initial commit.
1376
  itex2MML_free_string($3);
22 by Jacques Distler
SVG Environment
1377
}
1378
| BEGINENV SVG XMLSTRING ENDSVG {
1379
  $$ = itex2MML_copy3("<semantics><annotation-xml encoding=\"SVG1.1\">", $3, "</annotation-xml></semantics>");
1380
  itex2MML_free_string($3);
1381
}
1382
| BEGINENV SVG ENDSVG {
1383
  $$ = itex2MML_copy_string(" ");
1 by Jacques Distler
Initial commit.
1384
};
1385
1386
substack: SUBSTACK MROWOPEN tableRowList MROWCLOSE {
1387
  $$ = itex2MML_copy3("<mrow><mtable columnalign=\"center\" rowspacing=\"0.5ex\">", $3, "</mtable></mrow>");
1388
  itex2MML_free_string($3);
1389
};
1390
1391
array: ARRAY MROWOPEN tableRowList MROWCLOSE {
1392
  $$ = itex2MML_copy3("<mrow><mtable>", $3, "</mtable></mrow>");
1393
  itex2MML_free_string($3);
1394
}
1395
| ARRAY MROWOPEN ARRAYOPTS MROWOPEN arrayopts MROWCLOSE tableRowList MROWCLOSE {
1396
  char * s1 = itex2MML_copy3("<mrow><mtable ", $5, ">");
1397
  $$ = itex2MML_copy3(s1, $7, "</mtable></mrow>");
1398
  itex2MML_free_string(s1);
1399
  itex2MML_free_string($5);
1400
  itex2MML_free_string($7);
1401
};
1402
1403
arrayopts: anarrayopt {
1404
  $$ = itex2MML_copy_string($1);
1405
  itex2MML_free_string($1);
1406
}
1407
| arrayopts anarrayopt {
1408
  $$ = itex2MML_copy3($1, " ", $2);
1409
  itex2MML_free_string($1);
1410
  itex2MML_free_string($2);
1411
};
1412
1413
anarrayopt: collayout {
1414
  $$ = itex2MML_copy_string($1);
1415
  itex2MML_free_string($1);
1416
}
1417
| colalign {
1418
  $$ = itex2MML_copy_string($1);
1419
  itex2MML_free_string($1);
1420
}
1421
| rowalign {
1422
  $$ = itex2MML_copy_string($1);
1423
  itex2MML_free_string($1);
1424
}
1425
| align {
1426
  $$ = itex2MML_copy_string($1);
1427
  itex2MML_free_string($1);
1428
}
1429
| eqrows {
1430
  $$ = itex2MML_copy_string($1);
1431
  itex2MML_free_string($1);
1432
}
1433
| eqcols {
1434
  $$ = itex2MML_copy_string($1);
1435
  itex2MML_free_string($1);
1436
}
1437
| rowlines {
1438
  $$ = itex2MML_copy_string($1);
1439
  itex2MML_free_string($1);
1440
}
1441
| collines {
1442
  $$ = itex2MML_copy_string($1);
1443
  itex2MML_free_string($1);
1444
}
1445
| frame {
1446
  $$ = itex2MML_copy_string($1);
1447
  itex2MML_free_string($1);
1448
}
1449
| padding {
1450
  $$ = itex2MML_copy_string($1);
1451
  itex2MML_free_string($1);
1452
};
1453
1454
collayout: COLLAYOUT ATTRLIST {
1455
  $$ = itex2MML_copy2("columnalign=", $2);
1456
  itex2MML_free_string($2);
1457
};
1458
1459
colalign: COLALIGN ATTRLIST {
1460
  $$ = itex2MML_copy2("columnalign=", $2);
1461
  itex2MML_free_string($2);
1462
};
1463
1464
rowalign: ROWALIGN ATTRLIST {
1465
  $$ = itex2MML_copy2("rowalign=", $2);
1466
  itex2MML_free_string($2);
1467
};
1468
1469
align: ALIGN ATTRLIST {
1470
  $$ = itex2MML_copy2("align=", $2);
1471
  itex2MML_free_string($2);
1472
};
1473
1474
eqrows: EQROWS ATTRLIST {
1475
  $$ = itex2MML_copy2("equalrows=", $2);
1476
  itex2MML_free_string($2);
1477
};
1478
1479
eqcols: EQCOLS ATTRLIST {
1480
  $$ = itex2MML_copy2("equalcolumns=", $2);
1481
  itex2MML_free_string($2);
1482
};
1483
1484
rowlines: ROWLINES ATTRLIST {
1485
  $$ = itex2MML_copy2("rowlines=", $2);
1486
  itex2MML_free_string($2);
1487
};
1488
1489
collines: COLLINES ATTRLIST {
1490
  $$ = itex2MML_copy2("columnlines=", $2);
1491
  itex2MML_free_string($2);
1492
};
1493
1494
frame: FRAME ATTRLIST {
1495
  $$ = itex2MML_copy2("frame=", $2);
1496
  itex2MML_free_string($2);
1497
};
1498
1499
padding: PADDING ATTRLIST {
1500
  char * s1 = itex2MML_copy3("rowspacing=", $2, " columnspacing=");
1501
  $$ = itex2MML_copy2(s1, $2);
1502
  itex2MML_free_string(s1);
1503
  itex2MML_free_string($2);
1504
};
1505
1506
tableRowList: tableRow {
1507
  $$ = itex2MML_copy_string($1);
1508
  itex2MML_free_string($1);
1509
}
1510
| tableRowList ROWSEP tableRow {
1511
  $$ = itex2MML_copy3($1, " ", $3);
1512
  itex2MML_free_string($1);
1513
  itex2MML_free_string($3);
1514
};
1515
1516
tableRow: simpleTableRow {
1517
  $$ = itex2MML_copy3("<mtr>", $1, "</mtr>");
1518
  itex2MML_free_string($1);
1519
}
1520
| optsTableRow {
1521
  $$ = itex2MML_copy_string($1);
1522
  itex2MML_free_string($1);
1523
};
1524
1525
simpleTableRow: tableCell {
1526
  $$ = itex2MML_copy_string($1);
1527
  itex2MML_free_string($1);
1528
}
1529
| simpleTableRow COLSEP tableCell {
1530
  $$ = itex2MML_copy3($1, " ", $3);
1531
  itex2MML_free_string($1);
1532
  itex2MML_free_string($3);
1533
};
1534
1535
optsTableRow: ROWOPTS MROWOPEN rowopts MROWCLOSE simpleTableRow {
1536
  char * s1 = itex2MML_copy3("<mtr ", $3, ">");
1537
  $$ = itex2MML_copy3(s1, $5, "</mtr>");
1538
  itex2MML_free_string(s1);
1539
  itex2MML_free_string($3);
1540
  itex2MML_free_string($5);
1541
};
1542
1543
rowopts: arowopt {
1544
  $$ = itex2MML_copy_string($1);
1545
  itex2MML_free_string($1);
1546
}
1547
| rowopts arowopt {
1548
  $$ = itex2MML_copy3($1, " ", $2);
1549
  itex2MML_free_string($1);
1550
  itex2MML_free_string($2);
1551
};
1552
1553
arowopt: colalign {
1554
  $$ = itex2MML_copy_string($1);
1555
  itex2MML_free_string($1);
1556
}
1557
| rowalign {
1558
  $$ = itex2MML_copy_string($1);
1559
  itex2MML_free_string($1);
1560
};
1561
1562
tableCell:   {
1563
  $$ = itex2MML_copy_string("<mtd></mtd>");
1564
}
1565
| compoundTermList {
1566
  $$ = itex2MML_copy3("<mtd>", $1, "</mtd>");
1567
  itex2MML_free_string($1);
1568
}
1569
| CELLOPTS MROWOPEN cellopts MROWCLOSE compoundTermList {
1570
  char * s1 = itex2MML_copy3("<mtd ", $3, ">");
1571
  $$ = itex2MML_copy3(s1, $5, "</mtd>");
1572
  itex2MML_free_string(s1);
1573
  itex2MML_free_string($3);
1574
  itex2MML_free_string($5);
1575
};
1576
1577
cellopts: acellopt {
1578
  $$ = itex2MML_copy_string($1);
1579
  itex2MML_free_string($1);
1580
}
1581
| cellopts acellopt {
1582
  $$ = itex2MML_copy3($1, " ", $2);
1583
  itex2MML_free_string($1);
1584
  itex2MML_free_string($2);
1585
};
1586
1587
acellopt: colalign {
1588
  $$ = itex2MML_copy_string($1);
1589
  itex2MML_free_string($1);
1590
}
1591
| rowalign {
1592
  $$ = itex2MML_copy_string($1);
1593
  itex2MML_free_string($1);
1594
}
1595
| rowspan {
1596
  $$ = itex2MML_copy_string($1);
1597
  itex2MML_free_string($1);
1598
}
1599
| colspan {
1600
  $$ = itex2MML_copy_string($1);
1601
  itex2MML_free_string($1);
1602
};
1603
1604
rowspan: ROWSPAN ATTRLIST {
1605
  $$ = itex2MML_copy2("rowspan=", $2);
1606
  itex2MML_free_string($2);
1607
};
1608
1609
colspan: COLSPAN ATTRLIST {
8 by Jacques Distler
itex2MML 1.1.9;
1610
  $$ = itex2MML_copy2("columnspan=", $2);
1 by Jacques Distler
Initial commit.
1611
  itex2MML_free_string($2);
1612
};
1613
1614
%%
1615
1616
char * itex2MML_parse (const char * buffer, unsigned long length)
1617
{
1618
  char * mathml = 0;
1619
1620
  int result;
1621
1622
  itex2MML_setup (buffer, length);
1623
  itex2MML_restart ();
1624
1625
  result = itex2MML_yyparse (&mathml);
1626
1627
  if (result && mathml) /* shouldn't happen? */
1628
    {
1629
      itex2MML_free_string (mathml);
1630
      mathml = 0;
1631
    }
1632
  return mathml;
1633
}
1634
1635
int itex2MML_filter (const char * buffer, unsigned long length)
1636
{
1637
  itex2MML_setup (buffer, length);
1638
  itex2MML_restart ();
1639
1640
  return itex2MML_yyparse (0);
1641
}
1642
1643
#define ITEX_DELIMITER_DOLLAR 0
1644
#define ITEX_DELIMITER_DOUBLE 1
1645
#define ITEX_DELIMITER_SQUARE 2
1646
1647
static char * itex2MML_last_error = 0;
1648
1649
static void itex2MML_keep_error (const char * msg)
1650
{
1651
  if (itex2MML_last_error)
1652
    {
1653
      itex2MML_free_string (itex2MML_last_error);
1654
      itex2MML_last_error = 0;
1655
    }
1656
  itex2MML_last_error = itex2MML_copy_escaped (msg);
1657
}
1658
1659
int itex2MML_html_filter (const char * buffer, unsigned long length)
1660
{
23 by Jacques Distler
Angle Brackets
1661
  itex2MML_do_html_filter (buffer, length, 0);
1662
}
1663
1664
int itex2MML_strict_html_filter (const char * buffer, unsigned long length)
1665
{
1666
  itex2MML_do_html_filter (buffer, length, 1);
1667
}
1668
1669
int itex2MML_do_html_filter (const char * buffer, unsigned long length, const int forbid_markup)
1670
{
1 by Jacques Distler
Initial commit.
1671
  int result = 0;
1672
1673
  int type = 0;
1674
  int skip = 0;
1675
  int match = 0;
1676
1677
  const char * ptr1 = buffer;
1678
  const char * ptr2 = 0;
1679
1680
  const char * end = buffer + length;
1681
1682
  char * mathml = 0;
1683
1684
  void (*save_error_fn) (const char * msg) = itex2MML_error;
1685
1686
  itex2MML_error = itex2MML_keep_error;
1687
1688
 _until_math:
1689
  ptr2 = ptr1;
1690
1691
  while (ptr2 < end)
1692
    {
1693
      if (*ptr2 == '$') break;
1694
      if ((*ptr2 == '\\') && (ptr2 + 1 < end))
1695
	{
1696
	  if (*(ptr2+1) == '[') break;
1697
	}
1698
      ++ptr2;
1699
    }
45 by Jacques Distler
Fix a bug in itex2MML_html_filter
1700
  if (itex2MML_write && ptr2 > ptr1)
1 by Jacques Distler
Initial commit.
1701
    (*itex2MML_write) (ptr1, ptr2 - ptr1);
1702
1703
  if (ptr2 == end) goto _finish;
1704
1705
 _until_html:
1706
  ptr1 = ptr2;
1707
1708
  if (ptr2 + 1 < end)
1709
    {
1710
      if ((*ptr2 == '\\') && (*(ptr2+1) == '['))
1711
	{
1712
	  type = ITEX_DELIMITER_SQUARE;
1713
	  ptr2 += 2;
1714
	}
1715
      else if ((*ptr2 == '$') && (*(ptr2+1) == '$'))
1716
	{
1717
	  type = ITEX_DELIMITER_DOUBLE;
1718
	  ptr2 += 2;
1719
	}
1720
      else
1721
	{
1722
	  type = ITEX_DELIMITER_DOLLAR;
1723
	  ptr2 += 2;
1724
	}
1725
    }
1726
  else goto _finish;
1727
1728
  skip = 0;
1729
  match = 0;
1730
1731
  while (ptr2 < end)
1732
    {
1733
      switch (*ptr2)
1734
	{
1735
	case '<':
1736
	case '>':
23 by Jacques Distler
Angle Brackets
1737
	  if (forbid_markup == 1) skip = 1;
1 by Jacques Distler
Initial commit.
1738
	  break;
1739
1740
	case '\\':
1741
	  if (ptr2 + 1 < end)
1742
	    {
1743
	      if (*(ptr2 + 1) == '[')
1744
		{
1745
		  skip = 1;
1746
		}
1747
	      else if (*(ptr2 + 1) == ']')
1748
		{
1749
		  if (type == ITEX_DELIMITER_SQUARE)
1750
		    {
1751
		      ptr2 += 2;
1752
		      match = 1;
1753
		    }
1754
		  else
1755
		    {
1756
		      skip = 1;
1757
		    }
1758
		}
1759
	    }
1760
	  break;
1761
1762
	case '$':
1763
	  if (type == ITEX_DELIMITER_SQUARE)
1764
	    {
1765
	      skip = 1;
1766
	    }
1767
	  else if (ptr2 + 1 < end)
1768
	    {
1769
	      if (*(ptr2 + 1) == '$')
1770
		{
1771
		  if (type == ITEX_DELIMITER_DOLLAR)
1772
		    {
1773
		      ptr2++;
1774
		      match = 1;
1775
		    }
1776
		  else
1777
		    {
1778
		      ptr2 += 2;
1779
		      match = 1;
1780
		    }
1781
		}
1782
	      else
1783
		{
1784
		  if (type == ITEX_DELIMITER_DOLLAR)
1785
		    {
1786
		      ptr2++;
1787
		      match = 1;
1788
		    }
1789
		  else
1790
		    {
1791
		      skip = 1;
1792
		    }
1793
		}
1794
	    }
1795
	  else
1796
	    {
1797
	      if (type == ITEX_DELIMITER_DOLLAR)
1798
		{
1799
		  ptr2++;
1800
		  match = 1;
1801
		}
1802
	      else
1803
		{
1804
		  skip = 1;
1805
		}
1806
	    }
1807
	  break;
1808
1809
	default:
1810
	  break;
1811
	}
1812
      if (skip || match) break;
1813
1814
      ++ptr2;
1815
    }
1816
  if (skip)
1817
    {
1818
      if (type == ITEX_DELIMITER_DOLLAR)
1819
	{
1820
	  if (itex2MML_write)
1821
	    (*itex2MML_write) (ptr1, 1);
1822
	  ptr1++;
1823
	}
1824
      else
1825
	{
1826
	  if (itex2MML_write)
1827
	    (*itex2MML_write) (ptr1, 2);
1828
	  ptr1 += 2;
1829
	}
1830
      goto _until_math;
1831
    }
1832
  if (match)
1833
    {
1834
      mathml = itex2MML_parse (ptr1, ptr2 - ptr1);
1835
1836
      if (mathml)
1837
	{
1838
	  if (itex2MML_write_mathml)
1839
	    (*itex2MML_write_mathml) (mathml);
1840
	  itex2MML_free_string (mathml);
1841
	  mathml = 0;
1842
	}
1843
      else
1844
	{
1845
	  ++result;
1846
	  if (itex2MML_write)
1847
	    {
1848
	      if (type == ITEX_DELIMITER_DOLLAR)
1849
		(*itex2MML_write) ("<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><merror><mtext>", 0);
1850
	      else
1851
		(*itex2MML_write) ("<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><merror><mtext>", 0);
1852
1853
	      (*itex2MML_write) (itex2MML_last_error, 0);
1854
	      (*itex2MML_write) ("</mtext></merror></math>", 0);
1855
	    }
1856
	}
1857
      ptr1 = ptr2;
1858
1859
      goto _until_math;
1860
    }
1861
  if (itex2MML_write)
1862
    (*itex2MML_write) (ptr1, ptr2 - ptr1);
1863
1864
 _finish:
1865
  if (itex2MML_last_error)
1866
    {
1867
      itex2MML_free_string (itex2MML_last_error);
1868
      itex2MML_last_error = 0;
1869
    }
1870
  itex2MML_error = save_error_fn;
1871
1872
  return result;
1873
}