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
This commit is contained in:
George Tasker 2001-05-24 16:54:19 +00:00
parent a217777fb3
commit fad535eea3
4 changed files with 231 additions and 71 deletions

View File

@ -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());
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--;
}
// 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 '$':

View File

@ -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;

View File

@ -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);

View File

@ -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;