void CmdIntegral(int code) /****************************************************************************** purpose: converts integral symbol + the "exponent" and "subscript" fields parameter: type of operand ******************************************************************************/ { char *upper_limit = NULL; char *lower_limit = NULL; char cThis; /* is there an exponent/subscript ? */ cThis = getNonBlank(); if (cThis == '_') lower_limit = getBraceParam(); else if (cThis == '^') upper_limit = getBraceParam(); else ungetTexChar(cThis); if (upper_limit || lower_limit) { cThis = getNonBlank(); if (cThis == '_') lower_limit = getBraceParam(); else if (cThis == '^') upper_limit = getBraceParam(); else ungetTexChar(cThis); } fprintRTF(" \\\\I"); switch(code) { case 4 : fprintRTF("\\\\in( %c %c )\\\\I", g_field_separator, g_field_separator); /*\iiint --- fall through*/ case 3 : fprintRTF("\\\\in( %c %c )\\\\I", g_field_separator, g_field_separator); /* \iint --- fall through*/ case 0 : fprintRTF("\\\\in("); break; case 1 : fprintRTF("\\\\su("); break; case 2 : fprintRTF("\\\\pr("); break; default: diagnostics(ERROR, "Illegal code to CmdIntegral"); } if (lower_limit) ConvertString(lower_limit); fprintRTF("%c", g_field_separator); if (upper_limit) ConvertString(upper_limit); fprintRTF("%c )", g_field_separator); if (lower_limit) free(lower_limit); if (upper_limit) free(upper_limit); }
void CmdLim(int code) /****************************************************************************** purpose: handles \lim parameter: 0=\lim, 1=\limsup, 2=\liminf ******************************************************************************/ { char cThis, *s, *lower_limit=NULL; cThis = getNonBlank(); if (cThis == '_') lower_limit = getBraceParam(); else ungetTexChar(cThis); if (code == 0) s=strdup("lim"); else if (code == 1) s=strdup("lim sup"); else s=strdup("lim inf"); if (lower_limit) fprintRTF("\\\\a\\\\ac("); fprintRTF("%s",s); if (lower_limit) { fprintRTF("%c",g_field_separator); ConvertString(lower_limit); fprintRTF(")"); } free(s); }
static char * getAngleParam(void) /****************************************************************************** purpose: return bracketed parameter \item<1> ---> "1" \item<> ---> "" \item the ---> NULL ^ ^ ^ \item <1> ---> "1" \item <> ---> "" \item the ---> NULL ^ ^ ^ ******************************************************************************/ { char c, *text; c = getNonBlank(); if (c == '<') { text = getDelimitedText('<','>',TRUE); diagnostics(5, "getAngleParam [%s]", text); } else { ungetTexChar(c); text = NULL; diagnostics(5, "getAngleParam []"); } return text; }
void CmdBibitem(int code) { char *label, *key, *signet, *s, c; g_processing_list_environment=TRUE; CmdEndParagraph(0); CmdStartParagraph(FIRST_PAR); label = getBracketParam(); key = getBraceParam(); signet = strdup_nobadchars(key); s=ScanAux("bibcite", key, 0); if (label && !s) { /* happens when file needs to be latex'ed again */ diagnostics(WARNING,"file needs to be latexed again for references"); fprintRTF("["); ConvertString(label); fprintRTF("]"); } else { diagnostics(4,"CmdBibitem <%s>",s); if (g_document_bibstyle == BIBSTYLE_STANDARD) { // fprintRTF("["); fprintRTF("{\\v\\*\\bkmkstart BIB_%s}",signet); ConvertString(s); fprintRTF("{\\*\\bkmkend BIB_%s}",signet); // fprintRTF("]"); fprintRTF("."); fprintRTF("\\tab "); } /* else emit nothing for APALIKE */ } if (s) free(s); if (label) free(label); free(signet); free(key); c=getNonBlank(); ungetTexChar(c); }
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 preParse(char **body, char **header, char **label) /************************************************************************** purpose: obtain the next section of the latex file This is now a preparsing routine that breaks a file up into sections. Macro expansion happens here as well. \input and \include are also handled here. The reason for this routine is allow \labels to refer to sections. This routine reads text until a new section heading is found. The text is returned in body and the *next* header is returned in header. If no header follows then NULL is returned. **************************************************************************/ { int any_possible_match, found; char cNext, cThis, *s, *text, *next_header, *str, *p; int i; int possible_match[43]; char *command[43] = { "", /* 0 entry is for user definitions */ "", /* 1 entry is for user environments */ "\\begin{verbatim}", "\\begin{figure}", "\\begin{figure*}", "\\begin{equation}", "\\begin{equation*}", "\\begin{eqnarray}", "\\begin{eqnarray*}", "\\begin{table}", "\\begin{table*}", "\\begin{description}", "\\begin{comment}", "\\end{verbatim}", "\\end{figure}", "\\end{figure*}", "\\end{equation}", "\\end{equation*}", "\\end{eqnarray}", "\\end{eqnarray*}", "\\end{table}", "\\end{table*}", "\\end{description}", "\\end{comment}", "\\part", "\\chapter", "\\section", "\\subsection", "\\subsubsection", "\\section*", "\\subsection*", "\\subsubsection*", "\\label", "\\input", "\\include", "\\verb", "\\url", "\\nolinkurl", "\\newcommand", "\\def", "\\renewcommand", "\\endinput", "\\end{document}", }; int ncommands = 43; const int b_verbatim_item = 2; const int b_figure_item = 3; const int b_figure_item2 = 4; const int b_equation_item = 5; const int b_equation_item2 = 6; const int b_eqnarray_item = 7; const int b_eqnarray_item2 = 8; const int b_table_item = 9; const int b_table_item2 = 10; const int b_description_item = 11; const int b_comment_item = 12; const int e_verbatim_item = 13; const int e_figure_item = 14; const int e_figure_item2 = 15; const int e_equation_item = 16; const int e_equation_item2 = 17; const int e_eqnarray_item = 18; const int e_eqnarray_item2 = 19; const int e_table_item = 20; const int e_table_item2 = 21; const int e_description_item = 22; const int e_comment_item = 23; const int label_item = 32; const int input_item = 33; const int include_item = 34; const int verb_item = 35; const int url_item = 36; const int nolinkurl_item = 37; const int new_item = 38; const int def_item = 39; const int renew_item = 40; const int endinput_item = 41; const int e_document_item = 42; int bs_count = 0; /* number of backslashes encountered in a row */ size_t cmd_pos = 0; /* position of start of command relative to end of buffer */ int label_depth = 0; int i_match = 0; text = NULL; next_header = NULL; /* typically becomes \subsection{Cows eat grass} */ *body = NULL; *header = NULL; *label = NULL; PushTrackLineNumber(FALSE); reset_buffer(); while (1) { cThis = getRawTexChar(); while (cThis == '\0' && getParserDepth() > 0) { PopSource(); diagnostics(4,"parser depth is now %d", getParserDepth()); cThis = getRawTexChar(); } if (cThis == '\0') diagnostics(6, "[%ld] xchar=000 '\\0' (backslash count=%d)", section_buffer_end, bs_count); else if (cThis == '\n') diagnostics(6, "[%ld] xchar=012 '\\n' (backslash count=%d)", section_buffer_end, bs_count); else diagnostics(6, "[%ld] xchar=%03d '%c' (backslash count=%d)", section_buffer_end, (int) cThis, cThis, bs_count); cThis = skipBOM(cThis); add_chr_to_buffer(cThis); if (cThis == '\0') break; if (cThis == '%' && even(bs_count)) { int n = 1; /* remove initial % */ do { cNext = getRawTexChar(); add_chr_to_buffer(cNext); n++; } while (cNext != '\n' && cNext != '\0'); move_end_of_buffer(-n); if (0) show_buffer("percent"); continue; } /* cmd_pos > 0 means that we have encountered a '\' and some fraction of a command, e.g., '\sec', therefore the first time that a backslash is found then cmd_pos becomes 1, */ if (cThis == '\\') { bs_count++; if (odd(bs_count)) { /* avoid "\\section" and "\\\\section" */ for (i = 0; i < ncommands; i++) possible_match[i] = TRUE; cmd_pos = 1; continue; } } else bs_count = 0; if (cmd_pos == 0) continue; /* replace "\ " and "\\n" with a space */ if (cmd_pos == 1 && (cThis == '\n' || cThis == ' ') ) { move_end_of_buffer(-1); add_chr_to_buffer(' '); cmd_pos = 0; continue; } /* at this point we are have encountered a command and may have to do something. if it is a user definition, then the user definition is expanded here if it is a user environment, then expansion also happens here it it is something else then we may or may not have to mess with it. */ /* hack to convert '\begin {' --> '\begin{' */ if (cThis==' ' && (matches_buffer_tail("\\begin") || matches_buffer_tail("\\end")) ) { diagnostics(5, "matched '\\begin ' or '\\end '"); do {cThis = getRawTexChar();} while (cThis == ' '); } /* hack to convert '\begin{ ' --> '\begin{' */ if (cThis==' ' && (matches_buffer_tail("\\begin{") || matches_buffer_tail("\\end{")) ) { diagnostics(5, "matched '\\begin{ ' or '\\end{ '"); do {cThis = getRawTexChar();} while (cThis == ' '); } any_possible_match = FALSE; found = FALSE; /* is is possibly a user defined command? */ if (possible_match[0]) { possible_match[0] = maybeDefinition(section_buffer + section_buffer_end - cmd_pos + 1, cmd_pos - 1); if (possible_match[0]) { /* test to make sure \userdef is complete */ any_possible_match = TRUE; cNext = getRawTexChar(); /* wrong when cNext == '%' */ ungetTexChar(cNext); if (!isalpha((int) cNext)) { /* is macro name complete? */ *(section_buffer + section_buffer_end + 1) = '\0'; i = existsDefinition(section_buffer + section_buffer_end - cmd_pos + 1); if (i > -1) { diagnostics(4, "matched <%s> ", section_buffer + section_buffer_end - cmd_pos); if (cNext == ' ') { cNext = getNonSpace(); ungetTexChar(cNext); } move_end_of_buffer(-cmd_pos-1); /* remove \userdef */ str = expandDefinition(i); PushSource(NULL, str); free(str); cmd_pos = 0; bs_count = 0; continue; } } } } /* is it a user defined environment? */ if (possible_match[1]) { char *pp = section_buffer + section_buffer_end - cmd_pos; possible_match[1] = maybeEnvironment(pp, cmd_pos); if (possible_match[1] == TRUE) { any_possible_match = TRUE; cNext = getRawTexChar(); /* wrong when cNext == '%' */ /* \begin{name} or \end{name} will end with '}' */ if (cNext == '}') { char *ss = NULL; *(pp + cmd_pos + 1) = '\0'; if (*(pp + 1) == 'e') { i = existsEnvironment(pp + strlen("\\end{")); ss = expandEnvironment(i, CMD_END); } else { i = existsEnvironment(pp + strlen("\\begin{")); ss = expandEnvironment(i, CMD_BEGIN); } if (ss) { /* found */ diagnostics(5, "matched <%s}>", pp); diagnostics(5, "expanded to <%s>", ss); PushSource(NULL, ss); move_end_of_buffer(-cmd_pos-1); /* remove \begin{userenvironment} */ free(ss); cmd_pos = 0; continue; } } ungetTexChar(cNext); /* put the character back */ } } /* is it one of the commands listed above? */ for (i = 2; i < ncommands; i++) { if (possible_match[i]) { if (cThis == command[i][cmd_pos]) any_possible_match = TRUE; else possible_match[i] = FALSE; diagnostics(6,"cmd_pos = %d, char = %c, possible match %s, size=%d, possible=%d", \ cmd_pos,cThis,command[i],strlen(command[i]),possible_match[i]); } } i_match = -1; for (i = 2; i < ncommands; i++) { /* discover any exact matches */ if (possible_match[i]) { diagnostics(6, "testing for <%s>", command[i]); /* right length? */ if (cmd_pos+1 == strlen(command[i])) { if (i<=e_comment_item || i==e_comment_item) { /* these entries are complete matches */ found = TRUE; } else { /* these entries we need to be a bit more careful and check next character */ cNext = getRawTexChar(); ungetTexChar(cNext); /* this test for the end of commands may still need tweaking */ if (!isalpha(cNext) && cNext != '*') { found = TRUE; } } } } if (found == TRUE) { diagnostics(6,"preparse matched '%s'",command[i]); i_match = i; break; } } if (any_possible_match) cmd_pos++; else cmd_pos = 0; /* no possible matches, reset and wait for next '\\' */ if (!found) continue; if (i_match == endinput_item) { diagnostics(6, "\\endinput"); move_end_of_buffer(-9); /* remove \endinput */ PopSource(); cmd_pos = 0; /* keep looking */ continue; } /* \end{document} reached! Stop processing */ if (i_match == e_document_item) { diagnostics(6, "\\end{document}"); move_end_of_buffer(-strlen(command[e_document_item])); add_chr_to_buffer('\0'); safe_free(*header); *header = strdup(command[e_document_item]); p = section_buffer; while (*p==' ' || *p == '\n') p++; *body = strdup(p); PopTrackLineNumber(); diagnostics(6, "body = %s", section_buffer); diagnostics(6, "next header = '%s'", command[e_document_item]); return; } if (i_match == verb_item) { /* slurp \verb#text# */ char cc; cNext = getRawTexChar(); add_chr_to_buffer(cNext); diagnostics(6, "verb char = %c", cNext); do { cc = getRawTexChar(); add_chr_to_buffer(cc); } while (cc != cNext && cc != '\0'); cmd_pos = 0; /* reset the command position */ continue; } /* cannot ignore this because it may contain unescaped '%' */ if (i_match == url_item || i_match == nolinkurl_item) { char cc; do { cc = getRawTexChar(); add_chr_to_buffer(cc); } while (cc != '\0' && cc != '}'); cmd_pos = 0; /* reset the command position */ continue; } if (i_match == include_item) { CmdInclude(0); move_end_of_buffer(-strlen(command[i])); cmd_pos = 0; /* reset the command position */ continue; } if (i_match == input_item) { CmdInclude(1); move_end_of_buffer(-strlen(command[i])); cmd_pos = 0; /* reset the command position */ continue; } if (i_match == label_item) { char *tag; tag = getBraceParam(); /* append \label{tag} to the buffer */ add_chr_to_buffer('{'); add_str_to_buffer(tag); add_chr_to_buffer('}'); if (!(*label) && strlen(tag) && label_depth == 0) *label = strdup_nobadchars(tag); free(tag); cmd_pos = 0; /* keep looking */ continue; } /* process any new definitions */ if (i_match == def_item || i_match == new_item || i_match == renew_item) { cNext = getRawTexChar(); /* wrong when cNext == '%' */ ungetTexChar(cNext); if (isalpha((int) cNext)) /* is macro name complete? */ continue; move_end_of_buffer(-strlen(command[i])); /* do not include in buffer */ if (i_match == def_item) CmdNewDef(DEF_DEF); else if (i_match == new_item) CmdNewDef(DEF_NEW); else CmdNewDef(DEF_RENEW); cmd_pos = 0; /* keep looking */ continue; } if (i_match == b_figure_item || i_match == b_figure_item2 || i_match == b_equation_item || i_match == b_equation_item2 || i_match == b_eqnarray_item || i_match == b_eqnarray_item2 || i_match == b_table_item || i_match == b_table_item2 || i_match == b_description_item) { label_depth++; /* labels now will not be the section label */ cmd_pos = 0; continue; } if (i_match == e_figure_item || i_match == e_figure_item2 || i_match == e_equation_item || i_match == e_equation_item2 || i_match == e_eqnarray_item || i_match == e_eqnarray_item2 || i_match == e_table_item || i_match == e_table_item2 || i_match == e_description_item) { label_depth--; /* labels may now be the section label */ cmd_pos = 0; continue; } if (i_match == b_verbatim_item) { /* slurp environment ... toxic contents! */ s = getTexUntil(command[e_verbatim_item], TRUE); add_str_to_buffer(s); free(s); add_str_to_buffer(command[e_verbatim_item]); diagnostics(4,"matched \\end{verbatim}"); cmd_pos = 0; /* keep looking */ continue; } if (i_match == b_comment_item) { /* slurp environment ... toxic contents! */ s = getTexUntil(command[e_comment_item], TRUE); add_str_to_buffer(s); free(s); add_str_to_buffer(command[e_comment_item]); cmd_pos = 0; /* keep looking */ continue; } diagnostics(4, "possible end of section"); diagnostics(4, "label_depth = %d", label_depth); if (label_depth > 0) /* still in a \begin{xxx} environment? */ continue; /* actually found command to end the section */ diagnostics(4, "preParse() found command to end section"); s = getBraceParam(); next_header = strdup_together4(command[i], "{", s, "}"); free(s); move_end_of_buffer(-strlen(command[i])); add_chr_to_buffer('\0'); break; } /*eliminate white space at beginning of buffer */ p = section_buffer; while (*p==' ' || *p == '\n') p++; *body = strdup(p); safe_free(*header); *header = next_header; PopTrackLineNumber(); }
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); } }