%parse-param {char **ret_str} %{ #include #include #include #include #include "mtex2MML.h" #include "colors.h" #include "em.h" #include "environment.h" #include "string_extras.h" #include "string_dup.h" #include "../deps/uthash/uthash.h" struct css_colors *colors = NULL; #define YYSTYPE char * #define YYPARSE_PARAM_TYPE char ** #define YYPARSE_PARAM ret_str /* set max nesting. utterly arbitrary number determined from http://git.io/FlWHfw */ #define YYMAXDEPTH 430 /* #define YYDEBUG 1 yydebug = 1; */ #define YYERROR_VERBOSE 1 #define yytext mtex2MML_yytext UT_array *environment_data_stack; encaseType encase = NONE; extern int yylex (); extern char * yytext; int global_label = 1; int line_counter = 1; int delimiter_options = 0; static void mtex2MML_default_error (const char * msg) { if (msg) { fprintf(stderr, "Line: %d Error: %s\n", mtex2MML_lineno, msg); } } void (*mtex2MML_error) (const char * msg) = mtex2MML_default_error; static void yyerror (char **ret_str, const char * s) { char * msg = mtex2MML_copy3 (s, " at token ", yytext); if (mtex2MML_error) { (*mtex2MML_error) (msg); } mtex2MML_free_string (msg); } /* Note: If length is 0, then buffer is treated like a string; otherwise only length bytes are written. */ static void mtex2MML_default_write (const char * buffer, unsigned long length) { if (buffer) { if (length) { fwrite (buffer, 1, length, stdout); } else { fputs (buffer, stdout); } } } static void mtex2MML_default_write_mathml (const char * mathml) { if (mtex2MML_write) { (*mtex2MML_write) (mathml, 0); } } #ifdef mtex2MML_CAPTURE static char * mtex2MML_output_string = "" ; char * mtex2MML_output () { char * copy = (char *) malloc((mtex2MML_output_string ? strlen(mtex2MML_output_string) : 0) + 1); if (copy) { if (mtex2MML_output_string) { strcpy(copy, mtex2MML_output_string); if (*mtex2MML_output_string != '\0') { mtex2MML_free_string(mtex2MML_output_string); } } else { copy[0] = 0; } mtex2MML_output_string = ""; } return copy; } static void mtex2MML_capture (const char * buffer, unsigned long length) { if (buffer) { if (length) { unsigned long first_length = mtex2MML_output_string ? strlen(mtex2MML_output_string) : 0; char * copy = (char *) malloc(first_length + length + 1); if (copy) { if (mtex2MML_output_string) { strcpy(copy, mtex2MML_output_string); if (*mtex2MML_output_string != '\0') { mtex2MML_free_string(mtex2MML_output_string); } } else { copy[0] = 0; } strncat(copy, buffer, length); mtex2MML_output_string = copy; } } else { char * copy = mtex2MML_copy2(mtex2MML_output_string, buffer); if (*mtex2MML_output_string != '\0') { mtex2MML_free_string(mtex2MML_output_string); } mtex2MML_output_string = copy; } } } static void mtex2MML_capture_mathml (const char * buffer) { char * temp = mtex2MML_copy2(mtex2MML_output_string, buffer); if (*mtex2MML_output_string != '\0') { mtex2MML_free_string(mtex2MML_output_string); } mtex2MML_output_string = temp; } void (*mtex2MML_write) (const char * buffer, unsigned long length) = mtex2MML_capture; void (*mtex2MML_write_mathml) (const char * mathml) = mtex2MML_capture_mathml; #else void (*mtex2MML_write) (const char * buffer, unsigned long length) = mtex2MML_default_write; void (*mtex2MML_write_mathml) (const char * mathml) = mtex2MML_default_write_mathml; #endif char * mtex2MML_empty_string = (char *) ""; /* Create a copy of a string, adding space for extra chars */ char * mtex2MML_copy_string_extra (const char * str, unsigned extra) { char * copy = (char *) malloc(extra + (str ? strlen (str) : 0) + 1); if (copy) { if (str) { strcpy(copy, str); } else { copy[0] = 0; } } return copy ? copy : mtex2MML_empty_string; } /* Create a copy of a string, appending two strings */ char * mtex2MML_copy3 (const char * first, const char * second, const char * third) { int first_length = first ? strlen( first) : 0; int second_length = second ? strlen(second) : 0; int third_length = third ? strlen( third) : 0; char * copy = (char *) malloc(first_length + second_length + third_length + 1); if (copy) { if (first) { strcpy(copy, first); } else { copy[0] = 0; } if (second) { strcat(copy, second); } if ( third) { strcat(copy, third); } } return copy ? copy : mtex2MML_empty_string; } /* Create a copy of a string, appending a second string */ char * mtex2MML_copy2 (const char * first, const char * second) { return mtex2MML_copy3(first, second, 0); } /* Create a copy of a string */ char * mtex2MML_copy_string (const char * str) { return mtex2MML_copy3(str, 0, 0); } /* Create a copy of a string, escaping unsafe characters for XML */ char * mtex2MML_copy_escaped (const char * str) { unsigned long length = 0; const char * ptr1 = str; char * ptr2 = 0; char * copy = 0; if ( str == 0) { return mtex2MML_empty_string; } if (*str == 0) { return mtex2MML_empty_string; } while (*ptr1) { switch (*ptr1) { case '<': /* < */ case '>': /* > */ length += 4; break; case '&': /* & */ length += 5; break; case '\'': /* ' */ case '"': /* " */ case '-': /* - */ length += 6; break; default: length += 1; break; } ++ptr1; } copy = (char *) malloc (length + 1); if (copy) { ptr1 = str; ptr2 = copy; while (*ptr1) { switch (*ptr1) { case '<': strcpy (ptr2, "<"); ptr2 += 4; break; case '>': strcpy (ptr2, ">"); ptr2 += 4; break; case '&': /* & */ strcpy (ptr2, "&"); ptr2 += 5; break; case '\'': /* ' */ strcpy (ptr2, "'"); ptr2 += 6; break; case '"': /* " */ strcpy (ptr2, """); ptr2 += 6; break; case '-': /* - */ strcpy (ptr2, "-"); ptr2 += 6; break; default: *ptr2++ = *ptr1; break; } ++ptr1; } *ptr2 = 0; } return copy ? copy : mtex2MML_empty_string; } /* Returns a string representation of the global_label, and increments the label */ char * mtex2MML_global_label() { char * n = (char *) malloc(256); #ifdef _WIN32 _snprintf(n, 256, "%d", global_label); #else snprintf(n, 256, "%d", global_label); #endif global_label++; char *prefix = mtex2MML_copy3("(", n, ")"); mtex2MML_free_string(n); return prefix; } /* Create a hex character reference string corresponding to code */ char * mtex2MML_character_reference (unsigned long int code) { #define ENTITY_LENGTH 10 char * entity = (char *) malloc(ENTITY_LENGTH); sprintf(entity, "&#x%05lx;", code); return entity; } void mtex2MML_free_string (char * str) { if (str && str != mtex2MML_empty_string) { free(str); } } %} %left TEXOVER TEXOVERWITHDELIMS TEXATOP TEXATOPWITHDELIMS TEXABOVE TEXABOVEWITHDELIMS %token CHAR STARTMATH STARTDMATH ENDMATH MTEXT MI MIB MN MO LIMITS NOLIMITS SUP SUB MROWOPEN MROWCLOSE MATHOPEN MATHCLOSE MATHORD MATHPUNCT VCENTER LEFT RIGHT BIG BBIG BIGG BBIGG BIGL BBIGL BIGGL BBIGGL BIGM BBIGM BIGGM BBIGGM FRAC TFRAC DFRAC CFRAC GENFRAC OPERATORNAME MATHOP MATHBIN MATHREL MATHINNER MOP MOL MOLL MOF MOR PERIODDELIM COMMADELIM OTHERDELIM LEFTDELIM RIGHTDELIM MOS MOB SQRT ROOT OF LEFTROOT UPROOT BINOM TBINOM BRACE BRACK CHOOSE DBINOM UNDER BUILDREL OVER OVERBRACE OVERBRACKET UNDERLINE UNDERBRACE UNDERBRACKET UNDEROVER TENSOR MULTI ALIGNATVALUE ARRAYALIGN COLUMNALIGN ARRAY SPACECUBE HSPACE MOVELEFT MOVERIGHT RAISE LOWER PXSTRING COLSEP COLSEPSPACE ROWSEP NEWLINE ARRAYOPTS COLLAYOUT COLALIGN ROWALIGN ALIGN EQROWS EQCOLS ROWLINES COLLINES FRAME PADDING ATTRLIST ITALICS SANS TT ENCLOSE ENCLOSENOTATION ENCLOSEATTR ENCLOSETEXT BOLD BOXED FBOX HBOX MBOX BCANCELED XCANCELED CANCELEDTO NOT SLASHED PMB SCR RM BB ST END BBLOWERCHAR BBUPPERCHAR BBDIGIT CALCHAR FRAKCHAR CAL FRAK CLAP LLAP RLAP ROWOPTS TEXTSIZE OLDSTYLE SCSTY SCSIZE SCSCSIZE TINY TTINY SMALL NORMALSIZE LARGE LLARGE LLLARGE HUGE HHUGE DISPLAY TEXTSTY TEXTBOX TEXTSTRING COLORSTRING STYLESTRING VERBBOX VERBSTRING ACUTE GRAVE BREVE MATHRING XMLSTRING CELLOPTS ROWSPAN COLSPAN THINSPACE ENSPACE MEDSPACE THICKSPACE QUAD QQUAD NEGSPACE NEGMEDSPACE NEGTHICKSPACE STRUT MATHSTRUT SMASH PHANTOM HPHANTOM VPHANTOM HREF UNKNOWNCHAR EMPTYMROW STATLINE TOOLTIP TOGGLE TOGGLESTART TOGGLEEND FGHIGHLIGHT BGHIGHLIGHT COLORBOX SPACE NUMBER INTONE INTTWO INTTHREE OVERLEFTARROW OVERLEFTRIGHTARROW OVERRIGHTARROW UNDERLEFTARROW UNDERLEFTRIGHTARROW UNDERRIGHTARROW BAR WIDEBAR SKEW VEC WIDEVEC HAT WIDEHAT CHECK WIDECHECK TILDE WIDETILDE DOT DDOT DDDOT DDDDOT UNARYMINUS UNARYPLUS BEGINENV ENDENV EQUATION EQUATION_STAR EQALIGN EQALIGNNO MATRIX PMATRIX BMATRIX BBMATRIX VMATRIX VVMATRIX SUBARRAY SVG ENDSVG SMALLMATRIX CASES ALIGNED ALIGNENV ALIGNENV_STAR ALIGNAT ALIGNAT_STAR ALIGNEDAT GATHERED EQNARRAY EQNARRAY_STAR MULTLINE MULTLINE_STAR GATHER_STAR GATHER SUBSTACK SIDESET BMOD PMOD POD RMCHAR SCRCHAR PMBCHAR COLOR BGCOLOR LABEL TAG BBOX XARROW OPTARGOPEN OPTARGCLOSE MTEXNUM RAISEBOX NEG LATEXSYMBOL TEXSYMBOL VARINJLIM VARLIMINF VARLIMSUP VARPROJLIM %% doc: xmlmmlTermList {/* all processing done in body*/}; xmlmmlTermList: {/* nothing - do nothing*/} | char {/* proc done in body*/} | expression {/* all proc. in body*/} | xmlmmlTermList char {/* all proc. in body*/} | xmlmmlTermList expression {/* all proc. in body*/}; char: CHAR { mtex2MML_free_string($1); /* Do nothing...but what did this used to do? printf("%s", $1); */ }; expression: STARTMATH ENDMATH {/* empty math group - ignore*/} | STARTDMATH ENDMATH {/* ditto */} | STARTMATH compoundTermList ENDMATH { char ** r = (char **) ret_str; char * p = mtex2MML_copy3("", $2, ""); char * s = mtex2MML_copy3(p, $3, ""); mtex2MML_free_string(p); mtex2MML_free_string($2); mtex2MML_free_string($3); if (r) { (*r) = (s == mtex2MML_empty_string) ? 0 : s; } else { if (mtex2MML_write_mathml) (*mtex2MML_write_mathml) (s); mtex2MML_free_string(s); } } | STARTDMATH compoundTermList ENDMATH { char ** r = (char **) ret_str; char * p = mtex2MML_copy3("", $2, ""); char * s = mtex2MML_copy3(p, $3, ""); mtex2MML_free_string(p); mtex2MML_free_string($2); mtex2MML_free_string($3); if (r) { (*r) = (s == mtex2MML_empty_string) ? 0 : s; } else { if (mtex2MML_write_mathml) (*mtex2MML_write_mathml) (s); mtex2MML_free_string(s); } } | mathenv { char ** r = (char **) ret_str; char * p = mtex2MML_copy3("", $1, ""); char * s = mtex2MML_copy2(p, ""); mtex2MML_free_string(p); mtex2MML_free_string($1); if (r) { (*r) = (s == mtex2MML_empty_string) ? 0 : s; } else { if (mtex2MML_write_mathml) (*mtex2MML_write_mathml) (s); mtex2MML_free_string(s); } } /* plugs away some memory leaks when errors occur */ | compoundTermList error { mtex2MML_free_string($1); mtex2MML_free_string($2); YYABORT; } | compoundTerm error { mtex2MML_free_string($1); mtex2MML_free_string($2); YYABORT; } | error { YYABORT; }; /* tosses away the final token so that future parses are not affected */ compoundTermList: compoundTerm { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | compoundTermList compoundTerm { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; compoundTerm: mob SUB closedTerm SUP closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($3, " ", $5); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } else { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($3, " ", $5); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | MATHOP closedTerm SUB closedTerm SUP closedTerm { char * s1 = mtex2MML_copy3("", $2, ""); char * s2 = mtex2MML_copy3(s1, $4, $6); $$ = mtex2MML_copy2(s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($4); mtex2MML_free_string($6); } | OPERATORNAME closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $2, ""); $$ = mtex2MML_copy2(s1, $3); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | OPERATORNAME closedTerm SUB closedTerm SUP closedTerm closedTerm { char *s1 = mtex2MML_copy3("", $2, ""); char *s2 = mtex2MML_copy3(s1, $4, $6); $$ = mtex2MML_copy3(s2, "", $7); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($4); mtex2MML_free_string($6); mtex2MML_free_string($7); } | mob SUB closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } else { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } mtex2MML_free_string($1); mtex2MML_free_string($3); } | mob SUP closedTerm SUB closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($5, " ", $3); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | mob SUP closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } else { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } mtex2MML_free_string($1); mtex2MML_free_string($3); } | mob SUP closedTerm LIMITS SUB closedTerm { char * mo = mtex2MML_str_replace($1, "", ""); char * s1 = mtex2MML_copy2("", mo); char * s2 = mtex2MML_copy3($6, " ", $3); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(mo); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($6); } | mob SUP closedTerm NOLIMITS SUB closedTerm { char * mo = mtex2MML_str_replace($1, "", ""); char * s1 = mtex2MML_copy2("", mo); char * s2 = mtex2MML_copy3($6, " ", $3); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(mo); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($6); } | mib SUB closedTerm SUP closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($3, " ", $5); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } else { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($3, " ", $5); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | mib SUB closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } else { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } mtex2MML_free_string($1); mtex2MML_free_string($3); } | mib SUP closedTerm SUB closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($5, " ", $3); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } else { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($5, " ", $3); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | mib SUP closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } else { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); } mtex2MML_free_string($1); mtex2MML_free_string($3); } | mib LIMITS SUB closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($4); } | closedTerm SUB closedTerm SUP closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($3, " ", $5); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | closedTerm NOLIMITS SUB closedTerm SUP closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($4, " ", $6); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($4); mtex2MML_free_string($6); } | closedTerm SUP closedTerm SUB closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($5, " ", $3); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | closedTerm SUB closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); } | closedTerm SUP closedTerm { char * s1 = mtex2MML_copy3("", $1, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); } | SUB closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | SUP closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | closedTerm { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); }; closedTerm: array | cases | eqalign | eqalignno | unaryminus | unaryplus | mib | mtext { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | mi { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | mn { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | mo | tensor | multi | mfrac | mathopen | mathclose | mathord | mathpunct | vcenter | enclose | binom | brace | brack | choose | msqrt | mroot | leftroot | uproot | raisebox | munder | mover | bar | vec | hat | skew | acute | grave | breve | mathring | dot | ddot | dddot | ddddot | check | tilde | overleftarrow | overleftrightarrow | overrightarrow | underleftarrow | underleftrightarrow | underrightarrow | moverbrace | moverbracket | munderbrace | munderbracket | munderline | munderover | emptymrow | mathclap | mathllap | mathrlap | displaystyle | textstyle | textsize | scriptstyle | scriptsize | tiny | ttiny | small | normalsize | large | llarge | lllarge | huge | hhuge | scriptscriptsize | oldstyle | moveleft | moveright | raise | lower | italics | sans | mono | bold | roman | rmchars | script | scrchars | pmb | pmbchars | bbold | frak | not | slashed | bcanceled | xcanceled | canceledto | boxed | fbox | hbox | mbox | cal | space | textstring | verbstring | thinspace | medspace | thickspace | enspace | spacecube | quad | qquad | negspace | negmedspace | negthickspace | strut | mathstrut | smash | phantom | hphantom | vphantom | tex | latex | varinjlim | varliminf | varlimsup | varprojlm | href | statusline | tooltip | toggle | label | tag | fghighlight | bghighlight | colorbox | color | hspace | newline | buildrel | texover | texoverwithdelims | texatop | texatopwithdelims | texabove | texabovewithdelims | MROWOPEN closedTerm MROWCLOSE { $$ = mtex2MML_copy_string($2); mtex2MML_free_string($2); } | MROWOPEN compoundTermList MROWCLOSE { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | left compoundTermList right { char * s1 = mtex2MML_copy3("", $1, $2); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | mathenv | substack | sideset | bmod | pmod | pod | unrecognized; left: LEFT LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | LEFT OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | LEFT PERIODDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy_string(""); mtex2MML_free_string($2); }; right: RIGHT RIGHTDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | RIGHT OTHERDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | RIGHT PERIODDELIM { $$ = mtex2MML_copy_string(""); mtex2MML_free_string($2); }; bigdelim: BIG LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIG RIGHTDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIG OTHERDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIG LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIG RIGHTDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIG OTHERDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGG LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGG RIGHTDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGG OTHERDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGG LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGG RIGHTDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGG OTHERDELIM { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGL LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGL OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGL LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGL OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGGL LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGGL OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGGL LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGGL OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGM LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGM OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGM LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGM OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGGM LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BIGGM OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGGM LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | BBIGGM OTHERDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; unrecognized: UNKNOWNCHAR { $$ = mtex2MML_copy_string("Unknown character"); }; unaryminus: UNARYMINUS { $$ = mtex2MML_copy_string(""); }; unaryplus: UNARYPLUS { $$ = mtex2MML_copy_string("+"); }; varinjlim: VARINJLIM { $$ = mtex2MML_copy_string("lim"); }; varliminf: VARLIMINF { $$ = mtex2MML_copy_string("lim_"); }; varlimsup: VARLIMSUP { $$ = mtex2MML_copy_string("lim¯"); }; varprojlm: VARPROJLIM { $$ = mtex2MML_copy_string("lim"); }; mi: MI; mtext: MTEXT; mib: MIB { mtex2MML_rowposn=2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); }; mn: MN | MTEXNUM TEXTSTRING { mtex2MML_rowposn = 2; $$ = mtex2MML_copy_string($2); mtex2MML_free_string($2); }; mob: MOB { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); }; mo: mob | bigdelim | MO { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOL { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOLL { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOL LIMITS SUB closedTerm SUP closedTerm { if (mtex2MML_displaymode == 1) { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($4, " ", $6); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } else { char * s1 = mtex2MML_copy3("", $1, " "); char * s2 = mtex2MML_copy3($4, " ", $6); $$ = mtex2MML_copy3(s1, s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } mtex2MML_free_string($1); mtex2MML_free_string($4); mtex2MML_free_string($6); } | RIGHTDELIM { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | LEFTDELIM { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | OTHERDELIM { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOF { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | PERIODDELIM { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | COMMADELIM { $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOS { mtex2MML_rowposn=2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOP { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MOR { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $1, ""); mtex2MML_free_string($1); } | MATHBIN TEXTSTRING { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | MATHINNER TEXTSTRING { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | MATHREL TEXTSTRING { mtex2MML_rowposn = 2; $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; space: SPACE ST INTONE END ST INTTWO END ST INTTHREE END { char * s1 = mtex2MML_copy3(""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($6); mtex2MML_free_string($9); }; /* TODO: intentional no op -- figure this out */ label: LABEL ATTRLIST { $$ = mtex2MML_copy_string(""); mtex2MML_free_string($2); }; /* TODO: intentional no op -- figure this out */ tag: TAG ATTRLIST { $$ = mtex2MML_copy_string(""); mtex2MML_free_string($2); }; statusline: STATLINE TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3("", $3, ""); $$ = mtex2MML_copy3(s1, $2, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; tooltip: TOOLTIP TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3("", $3, ""); $$ = mtex2MML_copy3(s1, $2, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; toggle: TOGGLE closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $2, " "); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | TOGGLESTART compoundTermList TOGGLEEND { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; fghighlight: FGHIGHLIGHT ATTRLIST closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; bghighlight: BGHIGHLIGHT ATTRLIST closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; colorbox: COLORBOX ATTRLIST closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; color: COLOR ATTRLIST compoundTermList { char * s1; struct css_colors *c = NULL; HASH_FIND_STR( colors, $2, c ); if (HASH_COUNT(c) > 0) s1 = mtex2MML_copy3(""); else s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | BGCOLOR ATTRLIST compoundTermList { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | BBOX ST PXSTRING END closedTerm { float padding = mtex2MML_extract_number_from_pxstring($3); char *px = mtex2MML_extract_string_from_pxstring($3); char *dbl_px = mtex2MML_double_pixel(padding, px); char *s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s4, $5, ""); mtex2MML_free_string(px); mtex2MML_free_string(dbl_px); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string($3); mtex2MML_free_string($5); } | BBOX ST COLORSTRING END closedTerm { char *s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | BBOX ST COLORSTRING PXSTRING END closedTerm { char *s1 = mtex2MML_copy3(""); float padding = mtex2MML_extract_number_from_pxstring($4); char *px = mtex2MML_extract_string_from_pxstring($4); char *dbl_px = mtex2MML_double_pixel(padding, px); char *s2 = mtex2MML_copy3(s1, "", $6); $$ = mtex2MML_copy2(s6, ""); mtex2MML_free_string(px); mtex2MML_free_string(dbl_px); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string(s5); mtex2MML_free_string(s6); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($6); } | BBOX ST COLORSTRING STYLESTRING PXSTRING END closedTerm { char *s1 = mtex2MML_copy3(""); float padding = mtex2MML_extract_number_from_pxstring($5); char *px = mtex2MML_extract_string_from_pxstring($5); char *dbl_px = mtex2MML_double_pixel(padding, px); char *s3 = mtex2MML_copy3(s2, "", $7); $$ = mtex2MML_copy2(s7, ""); mtex2MML_free_string(px); mtex2MML_free_string(dbl_px); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string(s5); mtex2MML_free_string(s6); mtex2MML_free_string(s7); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); mtex2MML_free_string($7); }; mathrlap: RLAP closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mathllap: LLAP closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mathclap: CLAP closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; textstring: TEXTBOX TEXTSTRING { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; verbstring: VERBBOX VERBSTRING { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; displaystyle: DISPLAY MROWOPEN texover MROWCLOSE { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | DISPLAY compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; textstyle: TEXTSTY compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; textsize: TEXTSIZE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; scriptstyle: SCSTY compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; scriptsize: SCSIZE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; scriptscriptsize: SCSCSIZE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; oldstyle: OLDSTYLE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; tiny: TINY compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; ttiny: TTINY compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; small: SMALL compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; normalsize: NORMALSIZE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; large: LARGE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; llarge: LLARGE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; lllarge: LLLARGE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; huge: HUGE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; hhuge: HHUGE compoundTermList { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; lower: LOWER MROWOPEN PXSTRING MROWCLOSE closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($3); mtex2MML_free_string($5); } | LOWER PXSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($2); mtex2MML_free_string($3); }; moveleft: MOVELEFT MROWOPEN PXSTRING MROWCLOSE closedTerm { char * s1 = mtex2MML_copy3(""); char * s2 = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($5); } | MOVELEFT PXSTRING closedTerm { char * s1 = mtex2MML_copy3(""); char * s2 = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($3); }; moveright: MOVERIGHT MROWOPEN PXSTRING MROWCLOSE closedTerm { char * s1 = mtex2MML_copy3(""); char * s2 = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($5); } | MOVERIGHT PXSTRING closedTerm { char * s1 = mtex2MML_copy3(""); char * s2 = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($3); }; raise: RAISE MROWOPEN PXSTRING MROWCLOSE closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($3); mtex2MML_free_string($5); } | RAISE PXSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($2); mtex2MML_free_string($3); }; italics: ITALICS closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; sans: SANS closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mono: TT closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; not: NOT closedTerm { $$ = mtex2MML_copy3("", $2, "̸"); mtex2MML_free_string($2); }; slashed: SLASHED closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; bcanceled: BCANCELED closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; xcanceled: XCANCELED closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; canceledto: CANCELEDTO closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $3, ""); $$ = mtex2MML_copy3(s1, $2, ""); mtex2MML_free_string($2); mtex2MML_free_string($3); mtex2MML_free_string(s1); }; mathopen: MATHOPEN closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mathclose: MATHCLOSE closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mathord: MATHORD closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mathpunct: MATHPUNCT closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; enclose: ENCLOSE ST ENCLOSENOTATION ST ENCLOSETEXT ST { char * notation = mtex2MML_str_replace($3, ",", " "); char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(notation); mtex2MML_free_string(s1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | ENCLOSE ST ENCLOSENOTATION ST ENCLOSEATTR ST ENCLOSETEXT ST { char * notation = mtex2MML_str_replace($3, ",", " "); char * attr = mtex2MML_str_replace($5, ",", " "); if (strstr(attr, "arrow=1") != NULL) { mtex2MML_free_string(attr); attr = mtex2MML_str_replace($5, "arrow=1", ""); char *t = mtex2MML_copy_string(notation); mtex2MML_free_string(notation); notation = mtex2MML_copy2(t, " updiagonalarrow"); mtex2MML_free_string(t); } char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s2, $7, ""); mtex2MML_free_string(notation); mtex2MML_free_string(attr); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string($7); }; vcenter: VCENTER compoundTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; boxed: BOXED closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; fbox: FBOX closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; hbox: HBOX closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mbox: MBOX closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; bold: BOLD closedTerm { /* TODO: stupid hack to get bold mover working */ char * b = mtex2MML_str_replace($2, "", ""); $$ = mtex2MML_copy3("", b, ""); mtex2MML_free_string(b); mtex2MML_free_string($2); }; roman: RM ST rmchars END { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | RM rmchars { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; rmchars: RMCHAR { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rmchars rmchars { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; script: SCR ST scrchars END { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | SCR scrchars { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; scrchars: SCRCHAR { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | scrchars SCRCHAR { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; pmb: PMB ST pmbchars END { char * s1 = mtex2MML_copy3("", $3, ""); char * s2 = mtex2MML_copy3(s1, "", $3); $$ = mtex2MML_copy2(s2, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(s2); } | PMB pmbchars { char * s1 = mtex2MML_copy3("", $2, ""); char * s2 = mtex2MML_copy3(s1, "", $2); $$ = mtex2MML_copy2(s2, ""); mtex2MML_free_string($2); mtex2MML_free_string(s1); mtex2MML_free_string(s2); }; pmbchars: PMBCHAR { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | pmbchars PMBCHAR { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; bbold: BB ST bbchars END { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | BB bbchars { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; bbchars: bbchar { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | bbchars bbchar { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; bbchar: BBLOWERCHAR { $$ = mtex2MML_copy3("&", $1, "opf;"); mtex2MML_free_string($1); } | BBUPPERCHAR { $$ = mtex2MML_copy3("&", $1, "opf;"); mtex2MML_free_string($1); } | BBDIGIT { /* Blackboard digits 0-9 correspond to Unicode characters 0x1D7D8-0x1D7E1 */ char * end = $1 + 1; int code = 0x1D7D8 + strtoul($1, &end, 10); $$ = mtex2MML_character_reference(code); mtex2MML_free_string($1); }; frak: FRAK ST frakletters END { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | FRAK frakletters { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; frakletters: frakletter { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | frakletters frakletter { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; frakletter: FRAKCHAR { if (strcmp($1, " ") == 0) $$ = mtex2MML_copy_string(" "); else $$ = mtex2MML_copy3("&", $1, "fr;"); mtex2MML_free_string($1); }; cal: CAL ST calletters END { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | CAL calletters { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; calletters: calletter { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | calletters calletter { $$ = mtex2MML_copy2($1, $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; calletter: CALCHAR { if (strcmp($1, " ") == 0) $$ = mtex2MML_copy_string(" "); else $$ = mtex2MML_copy3("&", $1, "scr;"); mtex2MML_free_string($1); }; thinspace: THINSPACE { $$ = mtex2MML_copy_string(""); }; medspace: MEDSPACE { $$ = mtex2MML_copy_string(""); }; thickspace: THICKSPACE { $$ = mtex2MML_copy_string(""); }; enspace: ENSPACE { $$ = mtex2MML_copy_string(""); }; hspace: HSPACE MROWOPEN PXSTRING MROWCLOSE { $$ = mtex2MML_copy3(""); mtex2MML_free_string($3); } | HSPACE PXSTRING { $$ = mtex2MML_copy3(""); mtex2MML_free_string($2); }; spacecube: SPACECUBE ST PXSTRING ST ST PXSTRING ST ST PXSTRING ST { char * s1 = mtex2MML_copy3(""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($6); mtex2MML_free_string($9); }; quad: QUAD { $$ = mtex2MML_copy_string(""); }; qquad: QQUAD { $$ = mtex2MML_copy_string(""); }; negspace: NEGSPACE { $$ = mtex2MML_copy_string(""); }; negmedspace: NEGMEDSPACE { $$ = mtex2MML_copy_string(""); }; negthickspace: NEGTHICKSPACE { $$ = mtex2MML_copy_string(""); }; strut: STRUT { $$ = mtex2MML_copy_string(""); }; mathstrut: MATHSTRUT { $$ = mtex2MML_copy_string("("); }; smash: SMASH closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; phantom: PHANTOM closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; hphantom: HPHANTOM closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; vphantom: VPHANTOM closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; tex: TEXSYMBOL { $$ = mtex2MML_copy_string("TEX"); }; latex: LATEXSYMBOL { $$ = mtex2MML_copy_string("LATEX"); }; href: HREF TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s2, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($3); }; tensor: TENSOR closedTerm MROWOPEN subsupList MROWCLOSE { char * s1 = mtex2MML_copy3("", $2, $4); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($4); } | TENSOR closedTerm subsupList { char * s1 = mtex2MML_copy3("", $2, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; multi: MULTI MROWOPEN subsupList MROWCLOSE closedTerm MROWOPEN subsupList MROWCLOSE { char * s1 = mtex2MML_copy3("", $5, $7); char * s2 = mtex2MML_copy3("", $3, ""); $$ = mtex2MML_copy2(s1, s2); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string($7); } | MULTI MROWOPEN subsupList MROWCLOSE closedTerm EMPTYMROW { char * s1 = mtex2MML_copy2("", $5); char * s2 = mtex2MML_copy3("", $3, ""); $$ = mtex2MML_copy2(s1, s2); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($5); } | MULTI EMPTYMROW closedTerm MROWOPEN subsupList MROWCLOSE { char * s1 = mtex2MML_copy3("", $3, $5); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($3); mtex2MML_free_string($5); }; subsupList: subsupTerm { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | subsupList subsupTerm { $$ = mtex2MML_copy3($1, " ", $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; subsupTerm: SUB closedTerm SUP closedTerm { $$ = mtex2MML_copy3($2, " ", $4); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SUB closedTerm { $$ = mtex2MML_copy2($2, " "); mtex2MML_free_string($2); } | SUP closedTerm { $$ = mtex2MML_copy2(" ", $2); mtex2MML_free_string($2); } | SUB SUP closedTerm { $$ = mtex2MML_copy2(" ", $3); mtex2MML_free_string($3); }; mfrac: FRAC closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $2, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | TFRAC closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $2, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | DFRAC closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $2, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | CFRAC closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $2, ""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | GENFRAC MROWOPEN LEFTDELIM MROWCLOSE MROWOPEN RIGHTDELIM MROWCLOSE MROWOPEN PXSTRING MROWCLOSE compoundTermList compoundTermList compoundTermList { char *s1 = NULL, *s2 = NULL, *s3 = NULL, *s4 = NULL; int style = 0; sscanf ($11,"%d", &style); switch (style) { case 0: s1 = mtex2MML_copy3("", $3, ""); s3 = mtex2MML_copy3(s2, $12 , $13); s4 = mtex2MML_copy3(s3, "", ""); break; case 1: s1 = mtex2MML_copy3("", $3, ""); s3 = mtex2MML_copy3(s2, $12 , $13); s4 = mtex2MML_copy3(s3, "", ""); break; case 2: s1 = mtex2MML_copy3("", $3, ""); s3 = mtex2MML_copy3(s2, $12 , $13); s4 = mtex2MML_copy3(s3, "", ""); break; case 3: s1 = mtex2MML_copy3("", $3, ""); s3 = mtex2MML_copy3(s2, $12 , $13); s4 = mtex2MML_copy3(s3, "", ""); break; } $$ = mtex2MML_copy3(s4, $6, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string($3); mtex2MML_free_string($6); mtex2MML_free_string($9); mtex2MML_free_string($11); mtex2MML_free_string($12); mtex2MML_free_string($13); }; pod: POD closedTerm { $$ = mtex2MML_copy3( "(", $2, ")"); mtex2MML_free_string($2); }; pmod: PMOD closedTerm { $$ = mtex2MML_copy3( "(mod", $2, ")"); mtex2MML_free_string($2); }; bmod: BMOD closedTerm { $$ = mtex2MML_copy3( "mod", $2, ""); mtex2MML_free_string($2); }; buildrel: BUILDREL closedTerm TEXOVER closedTerm { char *s1 = mtex2MML_copy3("", $4, $2); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($4); }; texover: closedTerm TEXOVER closedTerm { char * s1 = mtex2MML_copy3("", $1, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); } | left compoundTermList TEXOVER compoundTermList right { char * s1 = mtex2MML_copy3("", $1, ""); char * s2 = mtex2MML_copy3($2, "", $4); char * s3 = mtex2MML_copy3("", $5, ""); $$ = mtex2MML_copy3(s1, s2, s3); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($1); mtex2MML_free_string($2); mtex2MML_free_string($4); mtex2MML_free_string($5); }; texoverwithdelims: closedTerm TEXOVERWITHDELIMS LEFTDELIM RIGHTDELIM closedTerm { char * s1 = mtex2MML_copy3("", $3, ""); char * s2 = mtex2MML_copy3(s1, $1, $5); char * s3 = mtex2MML_copy2(s2, ""); $$ = mtex2MML_copy3(s3, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); }; texatop: MROWOPEN compoundTermList TEXATOP compoundTermList MROWCLOSE { char * s1 = mtex2MML_copy3("", $2, ""); $$ = mtex2MML_copy3(s1, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($4); } | closedTerm TEXATOP closedTerm { char * s1 = mtex2MML_copy3("", $1, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); }; texatopwithdelims: closedTerm TEXATOPWITHDELIMS LEFTDELIM RIGHTDELIM closedTerm { char * s1 = mtex2MML_copy3("", $3, ""); char * s2 = mtex2MML_copy3(s1, $1, $5); char * s3 = mtex2MML_copy2(s2, ""); $$ = mtex2MML_copy3(s3, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); }; texabove: closedTerm TEXABOVE MROWOPEN PXSTRING MROWCLOSE closedTerm { char * s1 = mtex2MML_copy3(""); char * s2 = mtex2MML_copy3(s1, $1, $6); $$ = mtex2MML_copy2(s2, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($4); mtex2MML_free_string($6); }; texabovewithdelims: closedTerm TEXABOVEWITHDELIMS LEFTDELIM RIGHTDELIM PXSTRING closedTerm { char * s1 = mtex2MML_copy3("", $3, ""); char * s2 = mtex2MML_copy3(s1, "", $1); char * s4 = mtex2MML_copy3(s3, $6, ""); $$ = mtex2MML_copy3(s4, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); mtex2MML_free_string($6); }; binom: BINOM closedTerm closedTerm { char * s1 = mtex2MML_copy3("(", $2, $3); $$ = mtex2MML_copy2(s1, ")"); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | TBINOM closedTerm closedTerm { char * s1 = mtex2MML_copy3("(", $2, $3); $$ = mtex2MML_copy2(s1, ")"); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); } | DBINOM closedTerm closedTerm { char * s1 = mtex2MML_copy3("(", $2, $3); $$ = mtex2MML_copy2(s1, ")"); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; brace: closedTerm BRACE closedTerm { char * s1 = mtex2MML_copy3("{", $1, $3); $$ = mtex2MML_copy2(s1, "}"); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); }; brack: closedTerm BRACK closedTerm { char * s1 = mtex2MML_copy3("[", $1, $3); $$ = mtex2MML_copy2(s1, "]"); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); }; choose: closedTerm CHOOSE closedTerm { char * s1 = mtex2MML_copy3("(", $1, $3); $$ = mtex2MML_copy2(s1, ")"); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); }; underleftarrow: UNDERLEFTARROW closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; underleftrightarrow: UNDERLEFTRIGHTARROW closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; underrightarrow: UNDERRIGHTARROW closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; /* TODO: can't seem to get Lasem to render the entity name; hardcode hex code */ munderbrace: UNDERBRACE closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | UNDERBRACE closedTerm SUB closedTerm { char * s1 = mtex2MML_copy3("", $2, ""); $$ = mtex2MML_copy3(s1, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($4); } | UNDERBRACE closedTerm LIMITS SUB closedTerm { char * s1 = mtex2MML_copy3("", $2, ""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($5); } | UNDERBRACE closedTerm NOLIMITS SUB closedTerm { char * s1 = mtex2MML_copy3("", $2, ""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($5); }; munderbracket: UNDERBRACKET closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; munderline: UNDERLINE closedTerm { $$ = mtex2MML_copy3("", $2, "̲"); mtex2MML_free_string($2); }; moverbrace: OVERBRACE closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; moverbracket: OVERBRACKET closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; overleftarrow: OVERLEFTARROW closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; overleftrightarrow: OVERLEFTRIGHTARROW closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; overrightarrow: OVERRIGHTARROW closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; bar: BAR closedTerm { $$ = mtex2MML_copy3("", $2, "¯"); mtex2MML_free_string($2); } | WIDEBAR closedTerm { $$ = mtex2MML_copy3("", $2, "¯"); mtex2MML_free_string($2); }; vec: VEC closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); } | WIDEVEC closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; acute: ACUTE closedTerm { $$ = mtex2MML_copy3("", $2, "´"); mtex2MML_free_string($2); }; grave: GRAVE closedTerm { $$ = mtex2MML_copy3("", $2, "`"); mtex2MML_free_string($2); }; breve: BREVE closedTerm { $$ = mtex2MML_copy3("", $2, "˘"); mtex2MML_free_string($2); }; mathring: MATHRING closedTerm { $$ = mtex2MML_copy3("", $2, "˚"); mtex2MML_free_string($2); }; dot: DOT closedTerm { $$ = mtex2MML_copy3("", $2, "˙"); mtex2MML_free_string($2); }; ddot: DDOT closedTerm { $$ = mtex2MML_copy3("", $2, "¨"); mtex2MML_free_string($2); }; dddot: DDDOT closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; ddddot: DDDDOT closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; tilde: TILDE closedTerm { $$ = mtex2MML_copy3("", $2, "˜"); mtex2MML_free_string($2); } | WIDETILDE closedTerm { $$ = mtex2MML_copy3("", $2, "˜"); mtex2MML_free_string($2); }; check: CHECK closedTerm { $$ = mtex2MML_copy3("", $2, "ˇ"); mtex2MML_free_string($2); } | WIDECHECK closedTerm { $$ = mtex2MML_copy3("", $2, "ˇ"); mtex2MML_free_string($2); }; hat: HAT closedTerm { $$ = mtex2MML_copy3("", $2, "^"); mtex2MML_free_string($2); } | WIDEHAT closedTerm { $$ = mtex2MML_copy3("", $2, "^"); mtex2MML_free_string($2); }; skew: SKEW closedTerm ACUTE closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "´"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm BAR closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "¯"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm BREVE closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "˘"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm CHECK closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "ˇ"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm DOT closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "˙"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm DDOT closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "¨"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm DDDOT closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "⃛"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm DDDDOT closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "⃜"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm GRAVE closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "`"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm HAT closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "^"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm TILDE closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "˜"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm WIDEHAT closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "^"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); } | SKEW closedTerm WIDETILDE closedTerm { char * em_skew = mtex2MML_dbl2em($2); $$ = mtex2MML_implement_skew($4, em_skew, "^"); mtex2MML_free_string(em_skew); mtex2MML_free_string($2); mtex2MML_free_string($4); }; msqrt: SQRT closedTerm { $$ = mtex2MML_copy3("", $2, ""); mtex2MML_free_string($2); }; mroot: SQRT OPTARGOPEN compoundTermList OPTARGCLOSE closedTerm { char * s1 = mtex2MML_copy3("", $5, $3); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | ROOT closedTerm OF closedTerm { char * s1 = mtex2MML_copy3("", $4, $2); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($4); }; leftroot: LEFTROOT ST NUMBER END closedTerm { char * spacing = mtex2MML_root_pos_to_em($3); char *s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(spacing); mtex2MML_free_string($3); mtex2MML_free_string($5); }; uproot: UPROOT ST NUMBER END closedTerm { char * spacing = mtex2MML_root_pos_to_em($3); char *s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s2, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(spacing); mtex2MML_free_string($3); mtex2MML_free_string($5); }; raisebox: RAISEBOX TEXTSTRING TEXTSTRING TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($2); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); } | RAISEBOX NEG TEXTSTRING TEXTSTRING TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $6, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); mtex2MML_free_string($6); } | RAISEBOX TEXTSTRING TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s2, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($3); mtex2MML_free_string($4); } | RAISEBOX NEG TEXTSTRING TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s3, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($3); mtex2MML_free_string($4); mtex2MML_free_string($5); } | RAISEBOX TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s2, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($2); mtex2MML_free_string($3); } | RAISEBOX NEG TEXTSTRING closedTerm { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s2, $4, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($3); mtex2MML_free_string($4); }; munder: XARROW OPTARGOPEN compoundTermList OPTARGCLOSE EMPTYMROW { char * s1 = mtex2MML_copy3("", $1, ""); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($3); } | UNDER closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $3, $2); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; mover: XARROW closedTerm { char * s1 = mtex2MML_copy3("", $1, ""); $$ = mtex2MML_copy3(s1, $2, ""); mtex2MML_free_string(s1); mtex2MML_free_string($1); mtex2MML_free_string($2); } | OVER closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $3, $2); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); }; munderover: XARROW OPTARGOPEN compoundTermList OPTARGCLOSE closedTerm { char * s1 = mtex2MML_copy3("", $1, ""); char * s2 = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3(s2, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($1); mtex2MML_free_string($3); mtex2MML_free_string($5); } | UNDEROVER closedTerm closedTerm closedTerm { char * s1 = mtex2MML_copy3("", $4, $2); $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string(s1); mtex2MML_free_string($2); mtex2MML_free_string($3); mtex2MML_free_string($4); }; emptymrow: EMPTYMROW { $$ = mtex2MML_copy_string(""); }; mathenv: BEGINENV EQUATION tableRowList ENDENV EQUATION { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | BEGINENV EQUATION_STAR tableRowList ENDENV EQUATION_STAR { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | BEGINENV MATRIX tableRowList ENDENV MATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV GATHERED ARRAYALIGN END tableRowList ENDENV GATHERED { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s2, $5, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s2, $5, ""); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(row_data); } | BEGINENV GATHERED tableRowList ENDENV GATHERED { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV EQNARRAY tableRowList ENDENV EQNARRAY { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV EQNARRAY_STAR tableRowList ENDENV EQNARRAY_STAR { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV GATHER tableRowList ENDENV GATHER { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV GATHER_STAR tableRowList ENDENV GATHER_STAR { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV MULTLINE tableRowList ENDENV MULTLINE { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV MULTLINE_STAR tableRowList ENDENV MULTLINE_STAR { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV PMATRIX tableRowList ENDENV PMATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3("("); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ")"); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ")"); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV BMATRIX tableRowList ENDENV BMATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3("["); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, "]"); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, "]"); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV VMATRIX tableRowList ENDENV VMATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV BBMATRIX tableRowList ENDENV BBMATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3("{"); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, "}"); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, "}"); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV VVMATRIX tableRowList ENDENV VVMATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV SMALLMATRIX tableRowList ENDENV SMALLMATRIX { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV CASES tableRowList ENDENV CASES { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3("{"); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ALIGNED ARRAYALIGN END tableRowList ENDENV ALIGNED { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s2, $5, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s2, $5, ""); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(row_data); } | BEGINENV ALIGNED tableRowList ENDENV ALIGNED { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ALIGNENV tableRowList ENDENV ALIGNENV { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ALIGNENV_STAR tableRowList ENDENV ALIGNENV_STAR { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $3, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $3, ""); mtex2MML_free_string($3); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ALIGNAT ALIGNATVALUE END tableRowList ENDENV ALIGNAT { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $5, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ALIGNAT_STAR ALIGNATVALUE END tableRowList ENDENV ALIGNAT_STAR { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $5, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ALIGNEDAT ALIGNATVALUE END tableRowList ENDENV ALIGNEDAT { char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s1, $5, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string(s1); mtex2MML_free_string(row_data); } | BEGINENV ARRAY ARRAYALIGN ST columnAlignList END tableRowList ENDENV ARRAY { char *pipe_chars = mtex2MML_vertical_pipe_extract($5); char *column_align = mtex2MML_remove_excess_pipe_chars($5); char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s4, $7, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s4, $7, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string($3); mtex2MML_free_string($5); mtex2MML_free_string($7); mtex2MML_free_string(pipe_chars); mtex2MML_free_string(column_align); mtex2MML_free_string(row_data); } | BEGINENV ARRAY ST columnAlignList END tableRowList ENDENV ARRAY { char *pipe_chars = mtex2MML_vertical_pipe_extract($4); char *column_align = mtex2MML_remove_excess_pipe_chars($4); char *row_data = mtex2MML_combine_row_data(&environment_data_stack); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s3, $6, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s3, $6, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string($4); mtex2MML_free_string($6); mtex2MML_free_string(pipe_chars); mtex2MML_free_string(column_align); mtex2MML_free_string(row_data); } | BEGINENV SUBARRAY ST columnAlignList END tableRowList ENDENV SUBARRAY { char *pipe_chars = mtex2MML_vertical_pipe_extract($4); char *column_align = mtex2MML_remove_excess_pipe_chars($4); char * s1 = mtex2MML_copy3(""); if (encase == TOPENCLOSE) { char *t = mtex2MML_copy3(s2, $6, ""); $$ = mtex2MML_copy3("", t, ""); mtex2MML_free_string(t); } else $$ = mtex2MML_copy3(s2, $6, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string($4); mtex2MML_free_string($6); mtex2MML_free_string(pipe_chars); mtex2MML_free_string(column_align); } | BEGINENV SVG XMLSTRING ENDSVG { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | BEGINENV SVG ENDSVG { $$ = mtex2MML_copy_string(" "); }; columnAlignList: columnAlignList COLUMNALIGN { $$ = mtex2MML_copy3($1, " ", $2); mtex2MML_free_string($1); mtex2MML_free_string($2); } | COLUMNALIGN { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); }; substack: SUBSTACK MROWOPEN tableRowList MROWCLOSE { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); }; sideset: SIDESET MROWOPEN SUB closedTerm SUP closedTerm MROWCLOSE MROWOPEN SUB closedTerm SUP closedTerm MROWCLOSE closedTerm { char *s1 = mtex2MML_copy2("", ""); char *s2 = mtex2MML_copy3(s1, $4, ""); char *s3 = mtex2MML_copy3(s2, $6, ""); char *s4 = mtex2MML_copy3(s3, $14, ""); char *s5 = mtex2MML_copy3(s4, $10, $12); $$ = mtex2MML_copy2(s5, ""); mtex2MML_free_string(s1); mtex2MML_free_string(s2); mtex2MML_free_string(s3); mtex2MML_free_string(s4); mtex2MML_free_string(s5); mtex2MML_free_string($4); mtex2MML_free_string($6); mtex2MML_free_string($10); mtex2MML_free_string($12); mtex2MML_free_string($14); }; array: ARRAY MROWOPEN tableRowList MROWCLOSE { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); } | ARRAY MROWOPEN ARRAYOPTS MROWOPEN arrayopts MROWCLOSE tableRowList MROWCLOSE { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $7, ""); mtex2MML_free_string(s1); mtex2MML_free_string($5); mtex2MML_free_string($7); }; cases: CASES MROWOPEN tableRowList MROWCLOSE { $$ = mtex2MML_copy3("{", $3, ""); mtex2MML_free_string($3); }; eqalign: EQALIGN MROWOPEN tableRowList MROWCLOSE { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); }; eqalignno: EQALIGNNO MROWOPEN tableRowList MROWCLOSE { $$ = mtex2MML_copy3("", $3, ""); mtex2MML_free_string($3); }; arrayopts: anarrayopt { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | arrayopts anarrayopt { $$ = mtex2MML_copy3($1, " ", $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; anarrayopt: collayout { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | colalign { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rowalign { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | align { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | eqrows { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | eqcols { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rowlines { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | collines { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | frame { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | padding { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); }; collayout: COLLAYOUT ATTRLIST { $$ = mtex2MML_copy2("columnalign=", $2); mtex2MML_free_string($2); }; colalign: COLALIGN ATTRLIST { $$ = mtex2MML_copy2("columnalign=", $2); mtex2MML_free_string($2); }; rowalign: ROWALIGN ATTRLIST { $$ = mtex2MML_copy2("rowalign=", $2); mtex2MML_free_string($2); }; align: ALIGN ATTRLIST { $$ = mtex2MML_copy2("align=", $2); mtex2MML_free_string($2); }; eqrows: EQROWS ATTRLIST { $$ = mtex2MML_copy2("equalrows=", $2); mtex2MML_free_string($2); }; eqcols: EQCOLS ATTRLIST { $$ = mtex2MML_copy2("equalcolumns=", $2); mtex2MML_free_string($2); }; rowlines: ROWLINES ATTRLIST { $$ = mtex2MML_copy2("rowlines=", $2); mtex2MML_free_string($2); }; collines: COLLINES ATTRLIST { $$ = mtex2MML_copy2("columnlines=", $2); mtex2MML_free_string($2); }; frame: FRAME ATTRLIST { $$ = mtex2MML_copy2("frame=", $2); mtex2MML_free_string($2); }; padding: PADDING ATTRLIST { char * s1 = mtex2MML_copy3("rowspacing=", $2, " columnspacing="); $$ = mtex2MML_copy2(s1, $2); mtex2MML_free_string(s1); mtex2MML_free_string($2); }; tableRowList: tableRow { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | tableRowList ROWSEP tableRow { $$ = mtex2MML_copy3($1, " ", $3); mtex2MML_free_string($1); mtex2MML_free_string($3); }; tableRow: simpleTableRow { int has_eqn_number = mtex2MML_fetch_eqn_number(&environment_data_stack); if (has_eqn_number && strcmp($1, "") != 0) { char * n = mtex2MML_global_label(); char *s1 = mtex2MML_copy3("", n, $1); $$ = mtex2MML_copy2(s1, ""); mtex2MML_free_string(n); mtex2MML_free_string(s1); } else { $$ = mtex2MML_copy3("", $1, ""); } mtex2MML_free_string($1); } | optsTableRow { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); }; simpleTableRow: tableCell { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | simpleTableRow COLSEP tableCell { $$ = mtex2MML_copy3($1, " ", $3); mtex2MML_free_string($1); mtex2MML_free_string($3); }; optsTableRow: ROWOPTS MROWOPEN rowopts MROWCLOSE simpleTableRow { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string($3); mtex2MML_free_string($5); }; rowopts: arowopt { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rowopts arowopt { $$ = mtex2MML_copy3($1, " ", $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; arowopt: colalign { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rowalign { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); }; newline: NEWLINE { $$ = mtex2MML_copy_string(""); } tableCell: { $$ = mtex2MML_copy_string(""); } | compoundTermList { if (mtex2MML_current_env_type(&environment_data_stack) != ENV_MULTLINE && mtex2MML_current_env_type(&environment_data_stack) != ENV_MULTLINESTAR) { if (mtex2MML_current_env_type(&environment_data_stack) == ENV_ALIGNAT || mtex2MML_current_env_type(&environment_data_stack) == ENV_ALIGNATSTAR) { $$ = mtex2MML_copy3("", $1, ""); } else { $$ = mtex2MML_copy3("", $1, ""); } } else { int total_lines = mtex2MML_current_env_line_count(&environment_data_stack); if (line_counter == 1) { $$ = mtex2MML_copy3("", $1, ""); line_counter++; } else if (line_counter == total_lines) { $$ = mtex2MML_copy3("", $1, ""); } else { $$ = mtex2MML_copy3("", $1, ""); line_counter++; } } mtex2MML_free_string($1); } | CELLOPTS MROWOPEN cellopts MROWCLOSE compoundTermList { char * s1 = mtex2MML_copy3(""); $$ = mtex2MML_copy3(s1, $5, ""); mtex2MML_free_string(s1); mtex2MML_free_string($3); mtex2MML_free_string($5); }; cellopts: acellopt { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | cellopts acellopt { $$ = mtex2MML_copy3($1, " ", $2); mtex2MML_free_string($1); mtex2MML_free_string($2); }; acellopt: colalign { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rowalign { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | rowspan { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); } | colspan { $$ = mtex2MML_copy_string($1); mtex2MML_free_string($1); }; rowspan: ROWSPAN ATTRLIST { $$ = mtex2MML_copy2("rowspan=", $2); mtex2MML_free_string($2); }; colspan: COLSPAN ATTRLIST { $$ = mtex2MML_copy2("columnspan=", $2); mtex2MML_free_string($2); }; %% /* see http://git.io/vk8Sz */ void envdata_copy(void *_dst, const void *_src) { envdata_t *dst = (envdata_t*)_dst, *src = (envdata_t*)_src; dst->rowspacing = src->rowspacing ? string_dup(src->rowspacing) : NULL; dst->rowlines = src->rowlines ? string_dup(src->rowlines) : NULL; dst->environment_type = src->environment_type; utarray_new(dst->eqn_numbers, &ut_int_icd); utarray_concat(dst->eqn_numbers, src->eqn_numbers); dst->line_count = src->line_count; } void envdata_dtor(void *_elt) { envdata_t *elt = (envdata_t*)_elt; if (elt->rowspacing) { free(elt->rowspacing); } if (elt->rowlines) { free(elt->rowlines); } if (elt->eqn_numbers) { utarray_free(elt->eqn_numbers); } } UT_icd envdata_icd = {sizeof(envdata_t), NULL, envdata_copy, envdata_dtor}; void format_additions(const char *buffer, const int options) { utarray_new(environment_data_stack, &envdata_icd); if (colors == NULL) mtex2MML_create_css_colors(&colors); if (options) delimiter_options = options; else delimiter_options = MTEX2MML_DELIMITER_DEFAULT; encaseType *encase_pointer = (encaseType *)NONE; line_counter = 1; mtex2MML_env_replacements(&environment_data_stack, &encase_pointer, buffer); encase = (encaseType) encase_pointer; } void free_additions() { utarray_free(environment_data_stack); struct css_colors *c = NULL, *tmp; HASH_ITER(hh, colors, c, tmp) { HASH_DEL(colors, c); free(c); } } char * mtex2MML_global_parse (const char * buffer, unsigned long length, const int options, const int global_start) { global_label = global_start; return mtex2MML_parse(buffer, length, options); } char * mtex2MML_parse (const char * buffer, unsigned long length, const int options) { char * mathml = 0; int result; format_additions(buffer, options); mtex2MML_setup (buffer, length); mtex2MML_restart (); result = mtex2MML_yyparse (&mathml); free_additions(); /* See Bison documentation/maliciousness test: http://bit.ly/1IbpOja 1 if parse error, 2 if memory exhuastion, etc. */ if (result > 0) { if (mathml) { mtex2MML_free_string (mathml); mathml = 0; } return NULL; } return mathml; } UT_array ** mtex2MML_get_environment_data_stack() { return &environment_data_stack; } int mtex2MML_filter (const char * buffer, unsigned long length, const int options) { return mtex2MML_do_filter (buffer, length, 0, 0, options); } int mtex2MML_text_filter (const char * buffer, unsigned long length, const int options) { return mtex2MML_do_filter (buffer, length, 0, 1, options); } int mtex2MML_strict_filter (const char * buffer, unsigned long length, const int options) { return mtex2MML_do_filter (buffer, length, 1, 1, options); } static char * mtex2MML_last_error = 0; static void mtex2MML_keep_error (const char * msg) { if (mtex2MML_last_error) { mtex2MML_free_string (mtex2MML_last_error); mtex2MML_last_error = 0; } mtex2MML_last_error = mtex2MML_copy_escaped (msg); } int mtex2MML_delimiter_type(const int type) { if (delimiter_options == MTEX2MML_DELIMITER_DEFAULT) { return type & (MTEX2MML_DELIMITER_DOLLAR | MTEX2MML_DELIMITER_DOUBLE); } else { return delimiter_options & type; } } int mtex2MML_do_filter (const char * buffer, unsigned long length, const int forbid_markup, const int write, const int options) { global_label = 1; format_additions(buffer, options); int result = 0; int type = 0; int skip = 0; int match = 0; const char * ptr1 = buffer; const char * ptr2 = 0; const char * end = buffer + length; char * mathml = 0; void (*save_error_fn) (const char * msg) = mtex2MML_error; mtex2MML_error = mtex2MML_keep_error; _until_math: ptr2 = ptr1; /* Search for the first math part */ while (ptr2 < end) { if (*ptr2 == '$' && (mtex2MML_delimiter_type(MTEX2MML_DELIMITER_DOLLAR) || mtex2MML_delimiter_type(MTEX2MML_DELIMITER_DOUBLE))) { break; } if ((*ptr2 == '\\') && (ptr2 + 5 < end) && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_ENVIRONMENTS)) { if (*(ptr2+1) == 'b' && *(ptr2+2) == 'e' && *(ptr2+3) == 'g' && *(ptr2+4) == 'i' && *(ptr2+5) == 'n') { break; } } if ((*ptr2 == '\\') && (ptr2 + 1 < end)) { if (*(ptr2+1) == '[' && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_BRACKETS)) { break; } if (*(ptr2+1) == '(' && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_PARENS)) { break; } if (*(ptr2+1) == '$' && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_DOLLAR)) { ptr2++; } } ++ptr2; } if (mtex2MML_write && ptr2 > ptr1 && write) { (*mtex2MML_write) (ptr1, ptr2 - ptr1); } if (ptr2 == end) { goto _finish; } /*_until_html:*/ ptr1 = ptr2; if (ptr2 + 5 < end && (*ptr2 == '\\') && (*(ptr2+1) == 'b') && (*(ptr2+2) == 'e') && (*(ptr2+3) == 'g') && (*(ptr2+4) == 'i') && (*(ptr2+5) == 'n') && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_ENVIRONMENTS)) { type = MTEX2MML_DELIMITER_ENVIRONMENTS; ptr2 += 6; } else if (ptr2 + 1 < end) { if ((*ptr2 == '\\') && (*(ptr2+1) == '[' && *(ptr2 - 1) != '\\') && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_BRACKETS)) { type = MTEX2MML_DELIMITER_BRACKETS; ptr2 += 2; } else if ((*ptr2 == '$') && (*(ptr2+1) == '$') && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_DOUBLE)) { type = MTEX2MML_DELIMITER_DOUBLE; ptr2 += 2; } else if ((*ptr2 == '\\') && (*(ptr2+1) == '(' && *(ptr2 - 1) != '\\') && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_PARENS)) { type = MTEX2MML_DELIMITER_PARENS; ptr2 += 2; } else if ((*ptr2 == '$') && !isspace(*(ptr2+1)) && mtex2MML_delimiter_type(MTEX2MML_DELIMITER_DOLLAR)) { type = MTEX2MML_DELIMITER_DOLLAR; ptr2++; } } else { goto _finish; } skip = 0; match = 0; while (ptr2 < end) { switch (*ptr2) { case '<': case '>': if (forbid_markup == 1) { skip = 1; } break; case '\\': if (ptr2 + 1 < end) { if (*(ptr2 + 1) == '[' && type == MTEX2MML_DELIMITER_BRACKETS) { skip = 1; } else if (*(ptr2 + 1) == ']') { if (type == MTEX2MML_DELIMITER_BRACKETS) { ptr2 += 2; match = 1; } else { skip = 1; } } else if (*(ptr2 + 1) == '(' && type == MTEX2MML_DELIMITER_PARENS) { skip = 1; } else if (*(ptr2 + 1) == ')') { if (type == MTEX2MML_DELIMITER_PARENS) { ptr2 += 2; match = 1; } else { skip = 1; } } else if (ptr2 + 3 < end && type == MTEX2MML_DELIMITER_ENVIRONMENTS) { if (*(ptr2 + 1) == 'e' && *(ptr2 + 2) == 'n' && *(ptr2 + 3) == 'd') { ptr2 += 3; // {env} can be many things, so consider it closed when we find the first } after \end while (ptr2 < end && *ptr2 != '}') { ptr2++; } ptr2++; // include final } match = 1; } } else { ptr2++; } } break; case '\n': /* we hit a newline in an unclosed inline equation -- skip this string */ if (type == MTEX2MML_DELIMITER_DOLLAR || type == MTEX2MML_DELIMITER_PARENS) { skip = 1; } break; case '$': if (type == MTEX2MML_DELIMITER_BRACKETS || type == MTEX2MML_DELIMITER_PARENS || type == MTEX2MML_DELIMITER_ENVIRONMENTS) { // no op } else if (ptr2 + 1 < end) { if (*(ptr2 + 1) == '$') { if (type == MTEX2MML_DELIMITER_DOLLAR) { ptr2++; match = 1; } else { ptr2 += 2; match = 1; } } else { if (type == MTEX2MML_DELIMITER_DOLLAR) { if (isspace(*(ptr2 - 1))) { skip = 1; } else if (isdigit(*(ptr2 + 1))) { if (write) { (*mtex2MML_write) (ptr1, ptr2 - ptr1 + 2); } skip = 1; ptr2 += 2; ptr1 = ptr2; } else { ptr2++; match = 1; } } else { if (*(ptr2 - 1) != '\\') { skip = 1; } } } } else { if (type == MTEX2MML_DELIMITER_DOLLAR) { ptr2++; match = 1; } else { skip = 1; } } break; default: break; } if (skip || match) { break; } ++ptr2; } if (skip) { if (type == MTEX2MML_DELIMITER_DOLLAR) { if (mtex2MML_write && write) { (*mtex2MML_write) (ptr1, 1); } ptr1++; } else { if (mtex2MML_write && write) { (*mtex2MML_write) (ptr1, 2); } ptr1 += 2; } goto _until_math; } if (match) { mtex2MML_setup (ptr1, ptr2 - ptr1); mtex2MML_restart (); mtex2MML_yyparse (&mathml); if (mathml) { if (mtex2MML_write_mathml) { (*mtex2MML_write_mathml) (mathml); } mtex2MML_free_string (mathml); mathml = 0; } else { ++result; if (mtex2MML_write && write) { /* A problematic error? Just leave the text alone. */ (*mtex2MML_write) (ptr1, ptr2 - ptr1); } } ptr1 = ptr2; goto _until_math; } if (mtex2MML_write) { (*mtex2MML_write) (ptr1, ptr2 - ptr1); } _finish: if (mtex2MML_last_error) { mtex2MML_free_string (mtex2MML_last_error); mtex2MML_last_error = 0; } mtex2MML_error = save_error_fn; free_additions(); return result; }