From: George Tasker Date: Thu, 24 May 2001 16:54:19 +0000 (+0000) Subject: Added '_' checking that warns of the use of "_" or "\_" in the wrong places X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/fad535eea353fa1ce2f15e3053fc3b96e9a0b02d Added '_' checking that warns of the use of "_" or "\_" in the wrong places Added syntax checking for common documenting problems that tex2rtf does not handle properly (like \begin{verbatim} and others needing to be on a line by themselves) Syntax checking and curley brace matching can be turned on via the commandline, or the new OPTIONS menu choice if using a GUI. Both are OFF by default to match current behavior Compilation again possible now if wxUSE_DEBUG_CONTEXT is set to 0 in setup.h Various GUI glitches fixed git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10309 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/utils/tex2rtf/src/tex2any.cpp b/utils/tex2rtf/src/tex2any.cpp index 71ab0cf7b9..5821833d51 100644 --- a/utils/tex2rtf/src/tex2any.cpp +++ b/utils/tex2rtf/src/tex2any.cpp @@ -72,6 +72,26 @@ int hugeFont1 = 20; int HugeFont2 = 24; int HUGEFont3 = 28; +// All of these tokens MUST be found on a line by themselves (no other +// text) and must start at the first character of the line, or tex2rtf +// will fail to process them correctly (a limitation of tex2rtf, not TeX) +wxString syntaxTokens[] = +{ "\\begin{verbatim}", + "\\begin{toocomplex}", + "\\end{verbatim}", + "\\end{toocomplex}", + "\\verb", + "\\begin{comment}", + "\\end{comment}", + "\\verbatiminput", + "\\par", + "\\input", + "\\helpinput", + "\\include", + wxEmptyString +}; + + /* * USER-ADJUSTABLE SETTINGS * @@ -88,6 +108,8 @@ bool winHelp = FALSE; // Output in Windows Help format if TRUE, line bool isInteractive = FALSE; bool runTwice = FALSE; int convertMode = TEX_RTF; +bool checkCurleyBraces = FALSE; +bool checkSyntax = FALSE; bool headerRule = FALSE; bool footerRule = FALSE; bool compatibilityMode = FALSE; // If TRUE, maximum Latex compatibility @@ -395,7 +417,7 @@ bool readInVerbatim = FALSE; // Within a verbatim, but not nec. verbatiminput // Switched this off because e.g. \verb${$ causes it to fail. There is no // detection of \verb yet. -#define CHECK_BRACES 1 +// #define CHECK_BRACES 1 unsigned long leftCurly = 0; unsigned long rightCurly = 0; @@ -408,7 +430,7 @@ bool read_a_line(char *buf) buf[0] = 0; return FALSE; } - + int ch = -2; int bufIndex = 0; buf[0] = 0; @@ -430,24 +452,25 @@ bool read_a_line(char *buf) ch = getc(Inputs[CurrentInputIndex]); -#if CHECK_BRACES - if (ch == '{' && !readInVerbatim) - leftCurly++; - if (ch == '}' && !readInVerbatim) + if (checkCurleyBraces) { - rightCurly++; - if (rightCurly > leftCurly) - { - wxString errBuf; - errBuf.Printf("An extra right curly brace ('}') was detected at line %lu inside file %s",LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); - OnError((char *)errBuf.c_str()); - - // Reduce the count of right curly braces, so the mismatched count - // isn't reported on every line that has a '}' after the first mismatch - rightCurly--; - } + if (ch == '{' && !readInVerbatim) + leftCurly++; + if (ch == '}' && !readInVerbatim) + { + rightCurly++; + if (rightCurly > leftCurly) + { + wxString errBuf; + errBuf.Printf("An extra right curly brace ('}') was detected at line %lu inside file %s",LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); + OnError((char *)errBuf.c_str()); + + // Reduce the count of right curly braces, so the mismatched count + // isn't reported on every line that has a '}' after the first mismatch + rightCurly--; + } + } } -#endif if (ch != EOF) { @@ -496,14 +519,14 @@ bool read_a_line(char *buf) { // Convert embedded characters to RTF equivalents - switch(ch) - { - case 0xf6: // ö - case 0xe4: // ü - case 0xfc: // ü - case 0xd6: // Ö - case 0xc4: // Ä - case 0xdc: // Ü + switch(ch) + { + case 0xf6: // ö + case 0xe4: // ü + case 0xfc: // ü + case 0xd6: // Ö + case 0xc4: // Ä + case 0xdc: // Ü if (bufIndex+5 >= MAX_LINE_BUFFER_SIZE) { wxString errBuf; @@ -512,21 +535,21 @@ bool read_a_line(char *buf) OnError((char *)errBuf.c_str()); return FALSE; } - buf[bufIndex++]='\\'; - buf[bufIndex++]='"'; - buf[bufIndex++]='{'; - switch(ch) - { - case 0xf6:buf[bufIndex++]='o';break; // ö - case 0xe4:buf[bufIndex++]='a';break; // ä - case 0xfc:buf[bufIndex++]='u';break; // ü - case 0xd6:buf[bufIndex++]='O';break; // Ö - case 0xc4:buf[bufIndex++]='A';break; // Ä - case 0xdc:buf[bufIndex++]='U';break; // Ü - } - buf[bufIndex++]='}'; - break; - case 0xdf: // ß + buf[bufIndex++]='\\'; + buf[bufIndex++]='"'; + buf[bufIndex++]='{'; + switch(ch) + { + case 0xf6:buf[bufIndex++]='o';break; // ö + case 0xe4:buf[bufIndex++]='a';break; // ä + case 0xfc:buf[bufIndex++]='u';break; // ü + case 0xd6:buf[bufIndex++]='O';break; // Ö + case 0xc4:buf[bufIndex++]='A';break; // Ä + case 0xdc:buf[bufIndex++]='U';break; // Ü + } + buf[bufIndex++]='}'; + break; + case 0xdf: // ß if (bufIndex+5 >= MAX_LINE_BUFFER_SIZE) { wxString errBuf; @@ -535,13 +558,13 @@ bool read_a_line(char *buf) OnError((char *)errBuf.c_str()); return FALSE; } - buf[bufIndex++]='\\'; - buf[bufIndex++]='s'; - buf[bufIndex++]='s'; + buf[bufIndex++]='\\'; + buf[bufIndex++]='s'; + buf[bufIndex++]='s'; buf[bufIndex++]='\\'; buf[bufIndex++]='/'; - break; - default: + break; + default: if (bufIndex >= MAX_LINE_BUFFER_SIZE) { wxString errBuf; @@ -550,8 +573,42 @@ bool read_a_line(char *buf) OnError((char *)errBuf.c_str()); return FALSE; } - buf[bufIndex++] = ch; - break; + // If the current character read in is a '_', we need to check + // whether there should be a '\' before it or not + if (ch != '_') + { + buf[bufIndex++] = ch; + break; + } + + if (readInVerbatim) + { + // There should NOT be a '\' before the '_' + if ((bufIndex > 0 && (buf[bufIndex-1] == '\\')) && (buf[0] != '%')) + { + wxString errBuf; + errBuf.Printf("An underscore ('_') was detected at line %lu inside file %s that should NOT have a '\\' before it.",LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); + OnError((char *)errBuf.c_str()); + } + } + else + { + // There should be a '\' before the '_' + if (bufIndex == 0) + { + wxString errBuf; + errBuf.Printf("An underscore ('_') was detected at line %lu inside file %s that may need a '\\' before it.",LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); + OnError((char *)errBuf.c_str()); + } + else if ((buf[bufIndex-1] != '\\') && (buf[0] != '%')) // If it is a comment line, then no warnings + { + wxString errBuf; + errBuf.Printf("An underscore ('_') was detected at line %lu inside file %s that may need a '\\' before it.",LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); + OnError((char *)errBuf.c_str()); + } + } + buf[bufIndex++] = ch; + break; } // switch } // else } @@ -563,16 +620,19 @@ bool read_a_line(char *buf) if (CurrentInputIndex > 0) ch = ' '; // No real end of file CurrentInputIndex --; -#if CHECK_BRACES - if (leftCurly != rightCurly) + + if (checkCurleyBraces) { - wxString errBuf; - errBuf.Printf("Curly braces do not match inside file %s\n%lu opens, %lu closes", (const char*) currentFileName.c_str(),leftCurly,rightCurly); - OnError((char *)errBuf.c_str()); + if (leftCurly != rightCurly) + { + wxString errBuf; + errBuf.Printf("Curly braces do not match inside file %s\n%lu opens, %lu closes", (const char*) currentFileName.c_str(),leftCurly,rightCurly); + OnError((char *)errBuf.c_str()); + } + leftCurly = 0; + rightCurly = 0; } - leftCurly = 0; - rightCurly = 0; -#endif + if (readingVerbatim) { readingVerbatim = FALSE; @@ -730,6 +790,37 @@ bool read_a_line(char *buf) bool succ = read_a_line(buf); return succ; } + + if (checkSyntax) + { + wxString bufStr = buf; + int index = 0; + size_t pos = 0; + for (index=0; syntaxTokens[index] != wxEmptyString; index++) + { + pos = bufStr.find(syntaxTokens[index]); + if (pos != wxString::npos && pos != 0) + { + size_t commentStart = bufStr.find("%"); + if (commentStart == wxString::npos || commentStart > pos) + { + wxString errBuf; + if (syntaxTokens[index] == "\\verb") + { + errBuf.Printf("'%s$....$' was detected at line %lu inside file %s. Please replace this form with \\tt{....}", + syntaxTokens[index], LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); + } + else + { + errBuf.Printf("'%s' was detected at line %lu inside file %s that is not the only text on the line, starting at column one.", + syntaxTokens[index], LineNumbers[CurrentInputIndex], (const char*) currentFileName.c_str()); + } + OnError((char *)errBuf.c_str()); + } + } + } + } // checkSyntax + if (strncmp(buf, "\\begin{verbatim}", 16) == 0 || strncmp(buf, "\\begin{toocomplex}", 18) == 0) readInVerbatim = TRUE; @@ -737,14 +828,15 @@ bool read_a_line(char *buf) strncmp(buf, "\\end{toocomplex}", 16) == 0) readInVerbatim = FALSE; -#if CHECK_BRACES - if (ch == EOF && leftCurly != rightCurly) + if (checkCurleyBraces) { - wxString errBuf; - errBuf.Printf("Curly braces do not match inside file %s\n%lu opens, %lu closes", (const char*) currentFileName.c_str(),leftCurly,rightCurly); - OnError((char *)errBuf.c_str()); + if (ch == EOF && leftCurly != rightCurly) + { + wxString errBuf; + errBuf.Printf("Curly braces do not match inside file %s\n%lu opens, %lu closes", (const char*) currentFileName.c_str(),leftCurly,rightCurly); + OnError((char *)errBuf.c_str()); + } } -#endif return (ch == EOF); } // read_a_line @@ -921,6 +1013,9 @@ int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *e pos = 0; len = strlen(buffer); // Check for verbatim (or toocomplex, which comes to the same thing) + wxString bufStr = buffer; +// if (bufStr.find("\\begin{verbatim}") != wxString::npos || +// bufStr.find("\\begin{toocomplex}") != wxString::npos) if (strncmp(buffer, "\\begin{verbatim}", 16) == 0 || strncmp(buffer, "\\begin{toocomplex}", 18) == 0) { @@ -1007,7 +1102,6 @@ int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *e } pos ++; - // Try matching \end{environment} if (environment && FindEndEnvironment(buffer, &pos, environment)) { @@ -1139,8 +1233,8 @@ int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *e children.Append((wxObject *)chunk); } - else - { + else + { char *env = NULL; bool tmpParseToBrace = TRUE; TexMacroDef *def = MatchMacro(buffer, &pos, &env, &tmpParseToBrace); @@ -1237,7 +1331,7 @@ int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *e } // delete chunk; // Might delete children - } + } } else { @@ -1245,7 +1339,7 @@ int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *e } } else - { + { /* * If all else fails, we assume that we have * a pair of braces on their own, so return a `dummy' macro @@ -1278,7 +1372,7 @@ int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *e arg->macroId = chunk->macroId; pos = ParseArg(arg, arg->children, buffer, pos, NULL, TRUE, customMacroArgs); - } + } break; } case '$': diff --git a/utils/tex2rtf/src/tex2any.h b/utils/tex2rtf/src/tex2any.h index 22068f38a9..1660cb3575 100644 --- a/utils/tex2rtf/src/tex2any.h +++ b/utils/tex2rtf/src/tex2any.h @@ -216,6 +216,8 @@ extern bool winHelp; // Output in Windows Help format if TRUE, linear otherwise extern bool isInteractive; extern bool runTwice; extern int convertMode; +extern bool checkCurleyBraces; +extern bool checkSyntax; extern bool stopRunning; extern int mirrorMargins; extern bool headerRule; diff --git a/utils/tex2rtf/src/tex2rtf.cpp b/utils/tex2rtf/src/tex2rtf.cpp index 3c121934fa..b7a9d99127 100644 --- a/utils/tex2rtf/src/tex2rtf.cpp +++ b/utils/tex2rtf/src/tex2rtf.cpp @@ -281,6 +281,16 @@ bool MyApp::OnInit() } } } + else if (strcmp(argv[i], "-checkcurleybraces") == 0) + { + i ++; + checkCurleyBraces = TRUE; + } + else if (strcmp(argv[i], "-checksyntax") == 0) + { + i ++; + checkSyntax = TRUE; + } else { wxString buf; @@ -354,6 +364,14 @@ bool MyApp::OnInit() mode_menu->Append(TEX_MODE_HTML, "Output &HTML", "HTML World Wide Web hypertext file"); mode_menu->Append(TEX_MODE_XLP, "Output &XLP", "wxHelp hypertext help file"); + wxMenu *options_menu = new wxMenu; + + options_menu->Append(TEX_OPTIONS_CURELY_BRACE, "Curley brace matching", "Checks for mismatched curley braces",TRUE); + options_menu->Append(TEX_OPTIONS_SYNTAX_CHECKING, "Syntax checking", "Syntax checking for common errors",TRUE); + + options_menu->Check(TEX_OPTIONS_CURELY_BRACE, checkCurleyBraces); + options_menu->Check(TEX_OPTIONS_SYNTAX_CHECKING, checkSyntax); + wxMenu *help_menu = new wxMenu; help_menu->Append(TEX_HELP, "&Help", "Tex2RTF Contents Page"); @@ -363,6 +381,7 @@ bool MyApp::OnInit() menuBar->Append(file_menu, "&File"); menuBar->Append(macro_menu, "&Macros"); menuBar->Append(mode_menu, "&Conversion Mode"); + menuBar->Append(options_menu, "&Options"); menuBar->Append(help_menu, "&Help"); frame->SetMenuBar(menuBar); @@ -557,7 +576,9 @@ int MyApp::OnExit() // TODO: this simulates zero-memory leaks! // Otherwise there are just too many... #ifndef __WXGTK__ +#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT wxDebugContext::SetCheckpoint(); +#endif #endif return 0; @@ -599,6 +620,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(TEX_MODE_WINHELP, MyFrame::OnModeWinHelp) EVT_MENU(TEX_MODE_HTML, MyFrame::OnModeHTML) EVT_MENU(TEX_MODE_XLP, MyFrame::OnModeXLP) + EVT_MENU(TEX_OPTIONS_CURELY_BRACE, MyFrame::OnOptionsCurleyBrace) + EVT_MENU(TEX_OPTIONS_SYNTAX_CHECKING, MyFrame::OnOptionsSyntaxChecking) EVT_MENU(TEX_HELP, MyFrame::OnHelp) EVT_MENU(TEX_ABOUT, MyFrame::OnAbout) END_EVENT_TABLE() @@ -753,6 +776,34 @@ void MyFrame::OnModeXLP(wxCommandEvent& event) SetStatusText("In XLP mode.", 1); } +void MyFrame::OnOptionsCurleyBrace(wxCommandEvent& event) +{ + checkCurleyBraces = !checkCurleyBraces; + if (checkCurleyBraces) + { + SetStatusText("Checking curley braces: YES", 1); + } + else + { + SetStatusText("Checking curley braces: NO", 1); + } +} + + +void MyFrame::OnOptionsSyntaxChecking(wxCommandEvent& event) +{ + checkSyntax = !checkSyntax; + if (checkSyntax) + { + SetStatusText("Checking syntax: YES", 1); + } + else + { + SetStatusText("Checking syntax: NO", 1); + } +} + + void MyFrame::OnHelp(wxCommandEvent& event) { #if wxUSE_HELP @@ -920,7 +971,7 @@ bool Go(void) if (isInteractive) { wxString buf; - buf.Printf("Working, pass %d...", passNumber); + buf.Printf("Working, pass %d...Click CLOSE to abort", passNumber); frame->SetStatusText((char *)buf.c_str()); } #endif @@ -995,6 +1046,8 @@ bool Go(void) TexCleanUp(); startedSections = FALSE; + frame->SetStatusText("Aborted by user."); + OnInform("Sorry, unsuccessful."); OkToClose = TRUE; return FALSE; @@ -1033,6 +1086,11 @@ void OnInform(char *msg) #else if (isInteractive && frame) (*frame->textWindow) << msg << "\n"; +/* This whole block of code is just wrong I think. It would behave + completely wrong under anything other than MSW due to the ELSE + with no statement, and the cout calls would fail under MSW, as + the code in this block is compiled if !NO_GUI This code has been + here since v1.1 of this file too. - gt else #ifdef __WXMSW__ { @@ -1043,6 +1101,7 @@ void OnInform(char *msg) #ifdef __WXMSW__ {} #endif +*/ if (isInteractive) { Tex2RTFYield(TRUE); diff --git a/utils/tex2rtf/src/tex2rtf.h b/utils/tex2rtf/src/tex2rtf.h index 70f2156b6d..b25cf89970 100644 --- a/utils/tex2rtf/src/tex2rtf.h +++ b/utils/tex2rtf/src/tex2rtf.h @@ -38,6 +38,8 @@ class MyFrame: public wxFrame void OnModeWinHelp(wxCommandEvent& event); void OnModeHTML(wxCommandEvent& event); void OnModeXLP(wxCommandEvent& event); + void OnOptionsCurleyBrace(wxCommandEvent& event); + void OnOptionsSyntaxChecking(wxCommandEvent& event); void OnHelp(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -108,9 +110,12 @@ class ItemizeStruc: public wxObject #define TEX_MODE_HTML 11 #define TEX_MODE_XLP 12 -#define TEX_HELP 13 -#define TEX_ABOUT 14 -#define TEX_SAVE_FILE 15 +#define TEX_OPTIONS_CURELY_BRACE 13 +#define TEX_OPTIONS_SYNTAX_CHECKING 14 + +#define TEX_HELP 15 +#define TEX_ABOUT 16 +#define TEX_SAVE_FILE 17 extern TexChunk *currentMember; extern bool startedSections;