void CmdLeftRight(int code) /****************************************************************************** purpose : Handles \left \right to properly handle \left. or \right. would require prescanning the entire equation. ******************************************************************************/ { char delim; delim = getTexChar(); if (delim == '\\') /* might be \{ or \} */ delim = getTexChar(); if (code == 0) { diagnostics(4, "CmdLeftRight() ... \\left <%c>", delim); if (delim == '.') diagnostics(WARNING, "\\left. not supported"); fprintRTF(" \\\\b "); if (delim == '(' || delim == '.') fprintRTF("("); else if (delim == '{') fprintRTF("\\\\bc\\\\\\{ ("); else fprintRTF("\\\\bc\\\\%c (", delim); } else { fprintRTF(")"); if (delim == '.') diagnostics(WARNING, "\\right. not supported"); diagnostics(4, "CmdLeftRight() ... \\right <%c>", delim); } }
/****************************************************************************** purpose: converts \r accents from LaTeX to RTF ******************************************************************************/ void CmdRingChar(int code) { int n = RtfFontNumber("STIXGeneral"); char *cParam; if (code == 1) { char c, d; c = getTexChar(); d = getTexChar(); if (c!='2' || d != '3') { fprintf(stderr, "sorry only \\accent23 is supported \n"); return; } } cParam = getBraceParam(); switch (cParam[0]) { case 'A': fprintRTF("\\'c5"); break; case 'a': fprintRTF("\\'e5"); break; case 'U': putUnicodeChar(0x01,0x6E,'U'); break; case 'u': putUnicodeChar(0x01,0x6F,'u'); break; case 'w': putUnicodeChar(0x01,0x98,'w'); break; case 'y': putUnicodeChar(0x01,0x99,'y'); break; case '\0': fprintRTF("\\'b0"); break; default: fprintRTF("{\\f%d",n); fprintRTF("\\u778\\'b0}"); /* unicode combining character 0x030A */ ConvertString(cParam); break; } free(cParam); }
static char * SlurpDollarEquation(void) /****************************************************************************** purpose : reads an equation delimited by $...$ this routine is needed to handle $ x \mbox{if $x$} $ ******************************************************************************/ { int brace=0; int slash=0; int i; char *s, *t, *u; s = malloc(1024*sizeof(char)); t = s; for (i=0; i<1024; i++) { *t = getTexChar(); if (*t == '\\') slash++; else if (*t == '{' && (slash % 2) == 0 && !(i>5 && strncmp(t-5,"\\left{", 6)==0) && !(i>6 && strncmp(t-6,"\\right{", 7)==0)) brace++; else if (*t == '}' && (slash % 2) == 0 && !(i>5 && !strncmp(t-5,"\\left}", 6)) && !(i>6 && !strncmp(t-6,"\\right}", 7))) brace--; else if (*t == '$' && (slash % 2) == 0 && brace == 0) { break; } else slash = 0; t++; } *t = '\0'; u = strdup(s); /* return much smaller string */ free(s); /* release the big string */ return u; }
void TranslateCommand() /**************************************************************************** purpose: The function is called on a backslash in input file and tries to call the command-function for the following command. returns: success or not globals: fTex, fRtf, command-functions have side effects or recursive calls; global flags for convert ****************************************************************************/ { char cCommand[MAXCOMMANDLEN]; int i,mode; int cThis; cThis = getTexChar(); mode = GetTexMode(); diagnostics(5, "Beginning TranslateCommand() \\%c", cThis); switch (cThis) { case '}': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("\\}"); return; case '{': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("\\{"); return; case '#': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("#"); return; case '$': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("$"); return; case '&': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("&"); return; case '%': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("%%"); return; case '_': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("_"); return; case '\\': /* \\[1mm] or \\*[1mm] possible */ CmdSlashSlash(0); return; case ' ': case '\n': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF(" "); /* ordinary interword space */ skipSpaces(); return; /* \= \> \< \+ \- \' \` all have different meanings in a tabbing environment */ case '-': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); PushBrace(); } else fprintRTF("\\-"); return; case '+': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); PushBrace(); } return; case '<': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); PushBrace(); } return; case '>': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); CmdTabjump(); PushBrace(); } else CmdSpace(0.50); /* medium space */ return; case '`': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); PushBrace(); } else CmdLApostrophChar(0); return; case '\'': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); PushBrace(); return; } else CmdRApostrophChar(0); /* char ' =?= \' */ return; case '=': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (g_processing_tabbing){ (void) PopBrace(); CmdTabset(); PushBrace(); } else CmdMacronChar(0); return; case '~': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CmdTildeChar(0); return; case '^': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CmdHatChar(0); return; case '.': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CmdDotChar(0); return; case '\"': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CmdUmlauteChar(0); return; case '(': CmdEquation(EQN_RND_OPEN | ON); /*PushBrace();*/ return; case '[': CmdEquation(EQN_BRACKET_OPEN | ON); /*PushBrace();*/ return; case ')': CmdEquation(EQN_RND_CLOSE | OFF); /*ret = RecursionLevel - PopBrace();*/ return; case ']': CmdEquation(EQN_BRACKET_CLOSE | OFF); /*ret = RecursionLevel - PopBrace();*/ return; case '/': CmdIgnore(0); /* italic correction */ return; case '!': CmdIgnore(0); /* \! negative thin space */ return; case ',': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CmdSpace(0.33); /* \, produces a small space */ return; case ';': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CmdSpace(0.75); /* \; produces a thick space */ return; case '@': CmdIgnore(0); /* \@ produces an "end of sentence" space */ return; case '3': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); fprintRTF("{\\'df}"); /* german symbol 'รก' */ return; } /* LEG180498 Commands consist of letters and can have an optional * at the end */ for (i = 0; i < MAXCOMMANDLEN; i++) { if (!isalpha((int)cThis) && (cThis != '*')) { bool found_nl = FALSE; if (cThis == '%'){ /* put the % back and get the next char */ ungetTexChar('%'); cThis=getTexChar(); } /* all spaces after commands are ignored, a single \n may occur */ while (cThis == ' ' || (cThis == '\n' && !found_nl)) { if (cThis == '\n') found_nl = TRUE; cThis = getTexChar(); } ungetTexChar(cThis); /* put back first non-space char after command */ break; /* done skipping spaces */ } else cCommand[i] = cThis; cThis = getRawTexChar(); /* Necessary because % ends a command */ } cCommand[i] = '\0'; /* mark end of string with zero */ diagnostics(5, "TranslateCommand() <%s>", cCommand); if (i == 0) return; if (strcmp(cCommand,"begin")==0){ fprintRTF("{"); PushBrace(); } if (CallCommandFunc(cCommand)){ /* call handling function for command */ if (strcmp(cCommand,"end")==0) { ret = RecursionLevel - PopBrace(); fprintRTF("}"); } return; } if (TryDirectConvert(cCommand)) return; if (TryVariableIgnore(cCommand)) return; diagnostics(WARNING, "Command \\%s not found - ignored", cCommand); }
void Convert() /**************************************************************************** purpose: converts inputfile and writes result to outputfile globals: fTex, fRtf and all global flags for convert (see above) ****************************************************************************/ { char cThis = '\n'; char cLast = '\0'; char cNext; int mode, count,pending_new_paragraph; diagnostics(3, "Entering Convert ret = %d", ret); RecursionLevel++; PushLevels(); while ((cThis = getTexChar()) && cThis != '\0') { if (cThis == '\n') diagnostics(5, "Current character is '\\n' mode = %d ret = %d level = %d", GetTexMode(), ret, RecursionLevel); else diagnostics(5, "Current character is '%c' mode = %d ret = %d level = %d", cThis, GetTexMode(), ret, RecursionLevel); mode = GetTexMode(); pending_new_paragraph--; switch (cThis) { case '\\': PushLevels(); TranslateCommand(); CleanStack(); if (ret > 0) { diagnostics(5, "Exiting Convert via TranslateCommand ret = %d level = %d", ret, RecursionLevel); ret--; RecursionLevel--; return; } break; case '{': if (mode==MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); CleanStack(); PushBrace(); fprintRTF("{"); break; case '}': CleanStack(); ret = RecursionLevel - PopBrace(); fprintRTF("}"); if (ret > 0) { diagnostics(5, "Exiting Convert via '}' ret = %d level = %d", ret, RecursionLevel); ret--; RecursionLevel--; return; } break; case ' ': if (mode==MODE_VERTICAL || mode==MODE_MATH || mode==MODE_DISPLAYMATH) cThis = cLast; else if ( cLast != ' ' && cLast != '\n' ) { if (GetTexMode()==MODE_RESTRICTED_HORIZONTAL) fprintRTF("\\~"); else fprintRTF(" "); } break; case '\n': tabcounter = 0; if (mode==MODE_MATH || mode==MODE_DISPLAYMATH) { cNext = getNonBlank(); ungetTexChar(cNext); } else { cNext = getNonSpace(); if (cNext == '\n') { /* new paragraph ... skip all ' ' and '\n' */ pending_new_paragraph=2; CmdEndParagraph(0); cNext = getNonBlank(); ungetTexChar(cNext); } else { /* add a space if needed */ ungetTexChar(cNext); if (mode != MODE_VERTICAL && cLast != ' ') fprintRTF(" "); } } break; case '$': cNext = getTexChar(); diagnostics(5,"Processing $, next char <%c>",cNext); if (cNext == '$' && GetTexMode() != MODE_MATH) CmdEquation(EQN_DOLLAR_DOLLAR | ON); else { ungetTexChar(cNext); CmdEquation(EQN_DOLLAR | ON); } /* Formulas need to close all Convert() operations when they end This works for \begin{equation} but not $$ since the BraceLevel and environments don't get pushed properly. We do it explicitly here. */ /* if (GetTexMode() == MODE_MATH || GetTexMode() == MODE_DISPLAYMATH) PushBrace(); else { ret = RecursionLevel - PopBrace(); if (ret > 0) { ret--; RecursionLevel--; diagnostics(5, "Exiting Convert via Math ret = %d", ret); return; } } */ break; case '&': if (g_processing_arrays) { fprintRTF("%c",g_field_separator); break; } if (GetTexMode() == MODE_MATH || GetTexMode() == MODE_DISPLAYMATH) { /* in eqnarray */ fprintRTF("\\tab "); g_equation_column++; break; } if (g_processing_tabular) { /* in tabular */ actCol++; fprintRTF("\\cell\\pard\\intbl\\q%c ", colFmt[actCol]); break; } fprintRTF("&"); break; case '~': fprintRTF("\\~"); break; case '^': CmdSuperscript(0); break; case '_': CmdSubscript(0); break; case '-': if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) fprintRTF("-"); else { SetTexMode(MODE_HORIZONTAL); count = getSameChar('-')+1; if (count == 1) fprintRTF("-"); else if (count == 2) fprintRTF("\\endash "); else if (count == 3) fprintRTF("\\emdash "); else while (count--) fprintRTF("-"); } break; case '|': if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) fprintRTF("|"); else fprintRTF("\\emdash "); break; case '\'': if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) fprintRTF("'"); else { SetTexMode(MODE_HORIZONTAL); count = getSameChar('\'')+1; if (count == 2) fprintRTF("\\rdblquote "); else while (count--) fprintRTF("\\rquote "); } break; case '`': SetTexMode(MODE_HORIZONTAL); count = getSameChar('`')+1; if (count == 2) fprintRTF("\\ldblquote "); else while (count--) fprintRTF("\\lquote "); break; case '\"': SetTexMode(MODE_HORIZONTAL); if (GermanMode) TranslateGerman(); else fprintRTF("\""); break; case '<': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (GetTexMode() == MODE_HORIZONTAL){ cNext = getTexChar(); if (cNext == '<') { if (FrenchMode) { /* not quite right */ skipSpaces(); cNext = getTexChar(); if (cNext == '~') skipSpaces(); else ungetTexChar(cNext); fprintRTF("\\'ab\\~"); } else fprintRTF("\\'ab"); } else { ungetTexChar(cNext); fprintRTF("<"); } } else fprintRTF("<"); break; case '>': if (mode == MODE_VERTICAL) SetTexMode(MODE_HORIZONTAL); if (GetTexMode() == MODE_HORIZONTAL){ cNext = getTexChar(); if (cNext == '>') fprintRTF("\\'bb"); else { ungetTexChar(cNext); fprintRTF(">"); } } else fprintRTF(">"); break; case '!': if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) fprintRTF("!"); else { SetTexMode(MODE_HORIZONTAL); if ((cNext = getTexChar()) && cNext == '`') { fprintRTF("\\'a1 "); } else { fprintRTF("! "); ungetTexChar(cNext); } } break; case '?': SetTexMode(MODE_HORIZONTAL); if ((cNext = getTexChar()) && cNext == '`') { fprintRTF("\\'bf "); } else { fprintRTF("? "); ungetTexChar(cNext); } break; case ':': if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) fprintRTF(":"); else { SetTexMode(MODE_HORIZONTAL); if (FrenchMode) fprintRTF("\\~:"); else fprintRTF(":"); } break; case '.': if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) fprintRTF("."); else { SetTexMode(MODE_HORIZONTAL); fprintRTF("."); /* try to simulate double spaces after sentences */ cNext = getTexChar(); if (0 && cNext == ' ' && (isalpha((int)cLast) && !isupper((int) cLast))) fprintRTF(" "); ungetTexChar(cNext); } break; case '\t': diagnostics(WARNING, "This should not happen, ignoring \\t"); cThis = ' '; break; case '\r': diagnostics(WARNING, "This should not happen, ignoring \\r"); cThis = ' '; break; case '%': diagnostics(WARNING, "This should not happen, ignoring %%"); cThis = ' '; break; case '(': if (g_processing_fields&&g_escape_parent) fprintRTF("\\\\("); else fprintRTF("("); break; case ')': if (g_processing_fields&&g_escape_parent) fprintRTF("\\\\)"); else fprintRTF(")"); break; case ';': if (g_field_separator == ';' && g_processing_fields) fprintRTF("\\\\;"); else if (FrenchMode) fprintRTF("\\~;"); else fprintRTF(";"); break; case ',': if (g_field_separator == ',' && g_processing_fields) fprintRTF("\\\\,"); else fprintRTF(","); break; default: if (mode == MODE_MATH || mode == MODE_DISPLAYMATH) { if (('a' <= cThis && cThis <= 'z') || ('A' <= cThis && cThis <= 'Z')) fprintRTF("{\\i %c}", cThis); else fprintRTF("%c", cThis); } else { SetTexMode(MODE_HORIZONTAL); fprintRTF("%c", cThis); } break; } tabcounter++; cLast = cThis; } RecursionLevel--; diagnostics(5, "Exiting Convert via exhaustion ret = %d", ret); }
void CmdNot(int code) { char c, *s; c = getTexChar(); switch (c) { case '=': CmdUnicodeChar(8800); break; case '<': CmdUnicodeChar(8814); break; case '>': CmdUnicodeChar(8815); break; case '\\': ungetTexChar(c); s = getSimpleCommand(); if (strcmp(s,"\\leq")==0) CmdUnicodeChar(8816); else if (strcmp(s,"\\geq")==0) CmdUnicodeChar(8817); else if (strcmp(s,"\\equiv")==0) CmdUnicodeChar(8802); else if (strcmp(s,"\\prec")==0) CmdUnicodeChar(8832); else if (strcmp(s,"\\succ")==0) CmdUnicodeChar(8833); else if (strcmp(s,"\\sim")==0) CmdUnicodeChar(8769); else if (strcmp(s,"\\preceq")==0) CmdUnicodeChar(8928); else if (strcmp(s,"\\succeq")==0) CmdUnicodeChar(8929); else if (strcmp(s,"\\simeq")==0) CmdUnicodeChar(8772); else if (strcmp(s,"\\subset")==0) CmdUnicodeChar(8836); else if (strcmp(s,"\\supset")==0) CmdUnicodeChar(8837); else if (strcmp(s,"\\approx")==0) CmdUnicodeChar(8777); else if (strcmp(s,"\\subseteq")==0) CmdUnicodeChar(8840); else if (strcmp(s,"\\supseteq")==0) CmdUnicodeChar(8841); else if (strcmp(s,"\\cong")==0) CmdUnicodeChar(8775); else if (strcmp(s,"\\sqsubseteq")==0) CmdUnicodeChar(8930); else if (strcmp(s,"\\sqsupseteq")==0) CmdUnicodeChar(8931); else if (strcmp(s,"\\asymp")==0) CmdUnicodeChar(8813); else { fprintRTF("/"); ConvertString(s); } if (s) free(s); break; default: fprintRTF("/"); ungetTexChar(c); break; } }
/****************************************************************************** purpose: code = 0, handles \char'35 or \char"35 or \char35 or \char`b code = 1, handles \symbol{\'22} or \symbol{\"22} ******************************************************************************/ void CmdSymbol(int code) { char c, *s, *t; int n, base; if (code == 0) { char num[4]; int i; c = getNonSpace(); base = identifyBase(c); if (base == 0) { diagnostics(1,"malformed \\char construction"); fprintRTF("%c",c); return; } if (base == -1) { c = getTexChar(); /* \char`b case */ CmdChar((int) c); return; } if (base == 10) ungetTexChar(c); /* read sequence of digits */ for (i=0; i<4; i++) { num[i] = getTexChar(); if (base == 10 && ! isdigit(num[i]) ) break; if (base == 8 && ! isOctal(num[i]) ) break; if (base == 16 && ! isHex (num[i]) ) break; } ungetTexChar(num[i]); num[i] = '\0'; n = (int) strtol(num,&s,base); CmdChar(n); } else { s = getBraceParam(); t = strdup_noendblanks(s); free(s); base = identifyBase(*t); if (base == 0) return; if (base == -1) { CmdChar((int) *(t+1)); /* \char`b case */ return; } n = (int) strtol(t+1,&s,base); CmdChar(n); free(t); } }