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