1/////////////////////////////////////////////////////////////////////////////
2// Name:        tex2any.cpp
3// Purpose:     Utilities for Latex conversion.
4// Author:      Julian Smart
5// Modified by: Wlodzimierz ABX Skiba 2003/2004 Unicode support
6//              Ron Lee
7// Created:     01/01/99
8// RCS-ID:      $Id: tex2any.cpp 58387 2009-01-25 12:48:40Z VZ $
9// Copyright:   (c) Julian Smart
10// Licence:     wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17#pragma hdrstop
18#endif
19
20#ifndef WX_PRECOMP
21#endif
22
23#include <ctype.h>
24#include "tex2any.h"
25#include <stdlib.h>
26#include <time.h>
27
28#if !WXWIN_COMPATIBILITY_2_4
29static inline wxChar* copystring(const wxChar* s)
30    { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
31#endif
32
33/*
34 * Variables accessible from clients
35 *
36 */
37
38TexChunk *      DocumentTitle = NULL;
39TexChunk *      DocumentAuthor = NULL;
40TexChunk *      DocumentDate = NULL;
41
42// Header/footers/pagestyle
43TexChunk *      LeftHeaderEven = NULL;
44TexChunk *      LeftFooterEven = NULL;
45TexChunk *      CentreHeaderEven = NULL;
46TexChunk *      CentreFooterEven = NULL;
47TexChunk *      RightHeaderEven = NULL;
48TexChunk *      RightFooterEven = NULL;
49TexChunk *      LeftHeaderOdd = NULL;
50TexChunk *      LeftFooterOdd = NULL;
51TexChunk *      CentreHeaderOdd = NULL;
52TexChunk *      CentreFooterOdd = NULL;
53TexChunk *      RightHeaderOdd = NULL;
54TexChunk *      RightFooterOdd = NULL;
55wxChar *        PageStyle = copystring(_T("plain"));
56
57int             DocumentStyle = LATEX_REPORT;
58int             MinorDocumentStyle = 0;
59wxPathList      TexPathList;
60wxChar *        BibliographyStyleString = copystring(_T("plain"));
61wxChar *        DocumentStyleString = copystring(_T("report"));
62wxChar *        MinorDocumentStyleString = NULL;
63int             ParSkip = 0;
64int             ParIndent = 0;
65
66int             normalFont = 10;
67int             smallFont = 8;
68int             tinyFont = 6;
69int             largeFont1 = 12;
70int             LargeFont2 = 14;
71int             LARGEFont3 = 18;
72int             hugeFont1 = 20;
73int             HugeFont2 = 24;
74int             HUGEFont3 = 28;
75
76// All of these tokens MUST be found on a line by themselves (no other
77// text) and must start at the first character of the line, or tex2rtf
78// will fail to process them correctly (a limitation of tex2rtf, not TeX)
79static const wxString syntaxTokens[] =
80{ _T("\\begin{verbatim}"),
81  _T("\\begin{toocomplex}"),
82  _T("\\end{verbatim}"),
83  _T("\\end{toocomplex}"),
84  _T("\\verb"),
85  _T("\\begin{comment}"),
86  _T("\\end{comment}"),
87  _T("\\verbatiminput"),
88//  _T("\\par"),
89  _T("\\input"),
90  _T("\\helpinput"),
91  _T("\\include"),
92  wxEmptyString
93};
94
95
96/*
97 * USER-ADJUSTABLE SETTINGS
98 *
99 */
100
101// Section font sizes
102int             chapterFont =    12; // LARGEFont3;
103int             sectionFont =    12; // LargeFont2;
104int             subsectionFont = 12; // largeFont1;
105int             titleFont = LARGEFont3;
106int             authorFont = LargeFont2;
107int             mirrorMargins = true;
108bool            winHelp = false;  // Output in Windows Help format if true, linear otherwise
109bool            isInteractive = false;
110bool            runTwice = false;
111int             convertMode = TEX_RTF;
112bool            checkCurlyBraces = false;
113bool            checkSyntax = false;
114bool            headerRule = false;
115bool            footerRule = false;
116bool            compatibilityMode = false; // If true, maximum Latex compatibility
117                                // (Quality of RTF generation deteriorate)
118bool            generateHPJ; // Generate WinHelp Help Project file
119wxChar         *winHelpTitle = NULL; // Windows Help title
120int             defaultTableColumnWidth = 2000;
121
122int             labelIndentTab = 18;  // From left indent to item label (points)
123int             itemIndentTab = 40;   // From left indent to item (points)
124
125bool            useUpButton = true;
126int             htmlBrowseButtons = HTML_BUTTONS_TEXT;
127
128bool            truncateFilenames = false; // Truncate for DOS
129int             winHelpVersion = 3; // WinHelp Version (3 for Windows 3.1, 4 for Win95)
130bool            winHelpContents = false; // Generate .cnt file for WinHelp 4
131bool            htmlIndex = false; // Generate .htx file for HTML
132bool            htmlFrameContents = false; // Use frames for HTML contents page
133wxChar         *htmlStylesheet = NULL; // Use this CSS stylesheet for HTML pages
134bool            useHeadingStyles = true; // Insert \s1, s2 etc.
135bool            useWord = true; // Insert proper Word table of contents, etc etc
136int             contentsDepth = 4; // Depth of Word table of contents
137bool            indexSubsections = true; // Index subsections in linear RTF
138// Linear RTF method of including bitmaps. Can be "includepicture", "hex"
139wxChar         *bitmapMethod = copystring(_T("includepicture"));
140bool            upperCaseNames = false;
141// HTML background and text colours
142wxChar         *backgroundImageString = NULL;
143wxChar         *backgroundColourString = copystring(_T("255;255;255"));
144wxChar         *textColourString = NULL;
145wxChar         *linkColourString = NULL;
146wxChar         *followedLinkColourString = NULL;
147bool            combineSubSections = false;
148bool            htmlWorkshopFiles = false;
149bool            ignoreBadRefs = false;
150wxChar         *htmlFaceName = NULL;
151
152extern int passNumber;
153
154extern wxHashTable TexReferences;
155
156/*
157 * International support
158 */
159
160// Names to help with internationalisation
161wxChar *ContentsNameString = copystring(_T("Contents"));
162wxChar *AbstractNameString = copystring(_T("Abstract"));
163wxChar *GlossaryNameString = copystring(_T("Glossary"));
164wxChar *ReferencesNameString = copystring(_T("References"));
165wxChar *FiguresNameString = copystring(_T("List of Figures"));
166wxChar *TablesNameString = copystring(_T("List of Tables"));
167wxChar *FigureNameString = copystring(_T("Figure"));
168wxChar *TableNameString = copystring(_T("Table"));
169wxChar *IndexNameString = copystring(_T("Index"));
170wxChar *ChapterNameString = copystring(_T("chapter"));
171wxChar *SectionNameString = copystring(_T("section"));
172wxChar *SubsectionNameString = copystring(_T("subsection"));
173wxChar *SubsubsectionNameString = copystring(_T("subsubsection"));
174wxChar *UpNameString = copystring(_T("Up"));
175
176/*
177 * Section numbering
178 *
179 */
180
181int             chapterNo = 0;
182int             sectionNo = 0;
183int             subsectionNo = 0;
184int             subsubsectionNo = 0;
185int             figureNo = 0;
186int             tableNo = 0;
187
188/*
189 * Other variables
190 *
191 */
192
193FILE *CurrentOutput1 = NULL;
194FILE *CurrentOutput2 = NULL;
195FILE *Inputs[15];
196unsigned long LineNumbers[15];
197wxChar *FileNames[15];
198int CurrentInputIndex = 0;
199
200wxChar *TexFileRoot = NULL;
201wxChar *TexBibName = NULL;         // Bibliography output file name
202wxChar *TexTmpBibName = NULL;      // Temporary bibliography output file name
203bool isSync = false;             // If true, should not yield to other processes.
204bool stopRunning = false;        // If true, should abort.
205
206static int currentColumn = 0;
207wxChar *currentArgData = NULL;
208bool haveArgData = false; // If true, we're simulating the data.
209TexChunk *currentArgument = NULL;
210TexChunk *nextChunk = NULL;
211bool isArgOptional = false;
212int noArgs = 0;
213
214TexChunk *TopLevel = NULL;
215// wxList MacroDefs(wxKEY_STRING);
216wxHashTable MacroDefs(wxKEY_STRING);
217wxStringList IgnorableInputFiles; // Ignorable \input files, e.g. psbox.tex
218wxChar *BigBuffer = NULL;  // For reading in large chunks of text
219TexMacroDef *SoloBlockDef = NULL;
220TexMacroDef *VerbatimMacroDef = NULL;
221
222#define IncrementLineNumber() LineNumbers[CurrentInputIndex] ++
223
224
225TexRef::TexRef(const wxChar *label, const wxChar *file,
226               const wxChar *section, const wxChar *sectionN)
227{
228    refLabel = copystring(label);
229    refFile = file ? copystring(file) : (wxChar*) NULL;
230    sectionNumber = section ? copystring(section) : copystring(_T("??"));
231    sectionName = sectionN ? copystring(sectionN) : copystring(_T("??"));
232}
233
234TexRef::~TexRef(void)
235{
236    delete [] refLabel;      refLabel = NULL;
237    delete [] refFile;       refFile = NULL;
238    delete [] sectionNumber; sectionNumber = NULL;
239    delete [] sectionName;   sectionName = NULL;
240}
241
242
243CustomMacro::~CustomMacro()
244{
245    if (macroName)
246        delete [] macroName;
247    if (macroBody)
248        delete [] macroBody;
249}
250
251void TexOutput(const wxChar *s, bool ordinaryText)
252{
253  int len = wxStrlen(s);
254
255  // Update current column, but only if we're guaranteed to
256  // be ordinary text (not mark-up stuff)
257  int i;
258  if (ordinaryText)
259    for (i = 0; i < len; i++)
260    {
261      if (s[i] == 13 || s[i] == 10)
262        currentColumn = 0;
263      else
264        currentColumn ++;
265    }
266
267  if (CurrentOutput1)
268    wxFprintf(CurrentOutput1, _T("%s"), s);
269  if (CurrentOutput2)
270    wxFprintf(CurrentOutput2, _T("%s"), s);
271}
272
273/*
274 * Try to find a Latex macro, in one of the following forms:
275 * (1) \begin{} ... \end{}
276 * (2) \macroname{arg1}...{argn}
277 * (3) {\bf arg1}
278 */
279
280void ForbidWarning(TexMacroDef *def)
281{
282  wxString informBuf;
283  switch (def->forbidden)
284  {
285    case FORBID_WARN:
286    {
287      informBuf.Printf(_T("Warning: it is recommended that command %s is not used."), def->name);
288      OnInform((const wxChar *)informBuf.c_str());
289      break;
290    }
291    case FORBID_ABSOLUTELY:
292    {
293      informBuf.Printf(_T("Error: command %s cannot be used and will lead to errors."), def->name);
294      OnInform((const wxChar *)informBuf.c_str());
295      break;
296    }
297    default:
298      break;
299  }
300}
301
302TexMacroDef *MatchMacro(wxChar *buffer, int *pos, wxChar **env, bool *parseToBrace)
303{
304    *parseToBrace = true;
305    int i = (*pos);
306    TexMacroDef *def = NULL;
307    wxChar macroBuf[40];
308
309    // First, try to find begin{thing}
310    if (wxStrncmp(buffer+i, _T("begin{"), 6) == 0)
311    {
312        i += 6;
313
314        int j = i;
315        while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
316        {
317              macroBuf[j-i] = buffer[j];
318              j ++;
319        }
320        macroBuf[j-i] = 0;
321        def = (TexMacroDef *)MacroDefs.Get(macroBuf);
322
323        if (def)
324        {
325            *pos = j + 1;  // BUGBUG Should this be + 1???
326            *env = def->name;
327            ForbidWarning(def);
328            return def;
329        }
330        else
331        {
332            return NULL;
333        }
334    }
335
336    // Failed, so try to find macro from definition list
337    int j = i;
338
339    // First try getting a one-character macro, but ONLY
340    // if these TWO characters are not both alphabetical (could
341    // be a longer macro)
342    if (!(isalpha(buffer[i]) && isalpha(buffer[i+1])))
343    {
344        macroBuf[0] = buffer[i];
345        macroBuf[1] = 0;
346
347        def = (TexMacroDef *)MacroDefs.Get(macroBuf);
348        if (def) j ++;
349    }
350
351    if (!def)
352    {
353        while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
354        {
355            macroBuf[j-i] = buffer[j];
356            j ++;
357        }
358        macroBuf[j-i] = 0;
359        def = (TexMacroDef *)MacroDefs.Get(macroBuf);
360    }
361
362    if (def)
363    {
364        i = j;
365
366        // We want to check whether this is a space-consuming macro
367        // (e.g. {\bf word})
368        // No brace, e.g. \input thing.tex instead of \input{thing};
369        // or a numeric argument, such as \parindent0pt
370        if ((def->no_args > 0) && ((buffer[i] == 32) || (buffer[i] == '=') || (isdigit(buffer[i]))))
371        {
372            if ((buffer[i] == 32) || (buffer[i] == '='))
373            i ++;
374
375            *parseToBrace = false;
376        }
377        *pos = i;
378        ForbidWarning(def);
379        return def;
380    }
381    return NULL;
382}
383
384void EatWhiteSpace(wxChar *buffer, int *pos)
385{
386  int len = wxStrlen(buffer);
387  int j = *pos;
388  bool keepGoing = true;
389  bool moreLines = true;
390  while ((j < len) && keepGoing &&
391         (buffer[j] == 10 || buffer[j] == 13 || buffer[j] == ' ' || buffer[j] == 9))
392  {
393    j ++;
394    if (j >= len)
395    {
396      if (moreLines)
397      {
398        moreLines = read_a_line(buffer);
399        len = wxStrlen(buffer);
400        j = 0;
401      }
402      else
403        keepGoing = false;
404    }
405  }
406  *pos = j;
407}
408
409bool FindEndEnvironment(wxChar *buffer, int *pos, wxChar *env)
410{
411  int i = (*pos);
412
413  // Try to find end{thing}
414  if ((wxStrncmp(buffer+i, _T("end{"), 4) == 0) &&
415      (wxStrncmp(buffer+i+4, env, wxStrlen(env)) == 0))
416  {
417    *pos = i + 5 + wxStrlen(env);
418    return true;
419  }
420  else return false;
421}
422
423bool readingVerbatim = false;
424bool readInVerbatim = false;  // Within a verbatim, but not nec. verbatiminput
425
426// Switched this off because e.g. \verb${$ causes it to fail. There is no
427// detection of \verb yet.
428// #define CHECK_BRACES 1
429
430unsigned long leftCurly = 0;
431unsigned long rightCurly = 0;
432static wxString currentFileName = wxEmptyString;
433
434bool read_a_line(wxChar *buf)
435{
436  if (CurrentInputIndex < 0)
437  {
438    buf[0] = 0;
439    return false;
440  }
441
442  int ch = -2;
443  unsigned long bufIndex = 0;
444  buf[0] = 0;
445  int lastChar;
446
447  while (ch != EOF && ch != 10)
448  {
449    if (bufIndex >= MAX_LINE_BUFFER_SIZE)
450    {
451       wxString errBuf;
452       errBuf.Printf(_T("Line %lu of file %s is too long.  Lines can be no longer than %lu characters.  Truncated."),
453           LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str(), MAX_LINE_BUFFER_SIZE);
454       OnError((wxChar *)errBuf.c_str());
455       return false;
456    }
457
458    if (((bufIndex == 14) && (wxStrncmp(buf, _T("\\end{verbatim}"), 14) == 0)) ||
459         ((bufIndex == 16) && (wxStrncmp(buf, _T("\\end{toocomplex}"), 16) == 0)))
460      readInVerbatim = false;
461
462    lastChar = ch;
463    ch = getc(Inputs[CurrentInputIndex]);
464
465    if (checkCurlyBraces)
466    {
467        if (ch == '{' && !readInVerbatim && lastChar != _T('\\'))
468           leftCurly++;
469        if (ch == '}' && !readInVerbatim && lastChar != _T('\\'))
470        {
471           rightCurly++;
472           if (rightCurly > leftCurly)
473           {
474               wxString errBuf;
475               errBuf.Printf(_T("An extra right Curly brace ('}') was detected at line %lu inside file %s"), LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str());
476               OnError((wxChar *)errBuf.c_str());
477
478               // Reduce the count of right Curly braces, so the mismatched count
479               // isn't reported on every line that has a '}' after the first mismatch
480               rightCurly--;
481           }
482        }
483    }
484
485    if (ch != EOF)
486    {
487      // Check for 2 consecutive newlines and replace with \par
488      if (ch == 10 && !readInVerbatim)
489      {
490        int ch1 = getc(Inputs[CurrentInputIndex]);
491        if ((ch1 == 10) || (ch1 == 13))
492        {
493          // Eliminate newline (10) following DOS linefeed
494          if (ch1 == 13)
495            getc(Inputs[CurrentInputIndex]);
496          buf[bufIndex] = 0;
497          IncrementLineNumber();
498//          wxStrcat(buf, "\\par\n");
499//          i += 6;
500          if (bufIndex+5 >= MAX_LINE_BUFFER_SIZE)
501          {
502             wxString errBuf;
503             errBuf.Printf(_T("Line %lu of file %s is too long.  Lines can be no longer than %lu characters.  Truncated."),
504                 LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str(),MAX_LINE_BUFFER_SIZE);
505             OnError((wxChar *)errBuf.c_str());
506             return false;
507          }
508          wxStrcat(buf, _T("\\par"));
509          bufIndex += 5;
510
511        }
512        else
513        {
514          ungetc(ch1, Inputs[CurrentInputIndex]);
515          if (bufIndex >= MAX_LINE_BUFFER_SIZE)
516          {
517             wxString errBuf;
518             errBuf.Printf(_T("Line %lu of file %s is too long.  Lines can be no longer than %lu characters.  Truncated."),
519                 LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str(),MAX_LINE_BUFFER_SIZE);
520             OnError((wxChar *)errBuf.c_str());
521             return false;
522          }
523
524          buf[bufIndex] = (wxChar)ch;
525          bufIndex ++;
526        }
527      }
528      else
529      {
530
531        // Convert embedded characters to RTF equivalents
532        switch(ch)
533        {
534        case 0xf6: // �
535        case 0xe4: // �
536        case 0xfc: // �
537        case 0xd6: // �
538        case 0xc4: // �
539        case 0xdc: // �
540                if (bufIndex+5 >= MAX_LINE_BUFFER_SIZE)
541                {
542                   wxString errBuf;
543                   errBuf.Printf(_T("Line %lu of file %s is too long.  Lines can be no longer than %lu characters.  Truncated."),
544                       LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str(),MAX_LINE_BUFFER_SIZE);
545                   OnError((wxChar *)errBuf.c_str());
546                   return false;
547                }
548                buf[bufIndex++]='\\';
549                buf[bufIndex++]='"';
550                buf[bufIndex++]='{';
551                switch(ch)
552                {
553                    case 0xf6:buf[bufIndex++]='o';break; // �
554                    case 0xe4:buf[bufIndex++]='a';break; // �
555                    case 0xfc:buf[bufIndex++]='u';break; // �
556                    case 0xd6:buf[bufIndex++]='O';break; // �
557                    case 0xc4:buf[bufIndex++]='A';break; // �
558                    case 0xdc:buf[bufIndex++]='U';break; // �
559                }
560                buf[bufIndex++]='}';
561                break;
562        case 0xdf: // �
563            if (bufIndex+5 >= MAX_LINE_BUFFER_SIZE)
564            {
565              wxString errBuf;
566              errBuf.Printf(_T("Line %lu of file %s is too long.  Lines can be no longer than %lu characters.  Truncated."),
567                  LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str(),MAX_LINE_BUFFER_SIZE);
568              OnError((wxChar *)errBuf.c_str());
569              return false;
570            }
571            buf[bufIndex++]='\\';
572            buf[bufIndex++]='s';
573            buf[bufIndex++]='s';
574            buf[bufIndex++]='\\';
575            buf[bufIndex++]='/';
576            break;
577        default:
578            if (bufIndex >= MAX_LINE_BUFFER_SIZE)
579            {
580              wxString errBuf;
581              errBuf.Printf(_T("Line %lu of file %s is too long.  Lines can be no longer than %lu characters.  Truncated."),
582                  LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str(),MAX_LINE_BUFFER_SIZE);
583              OnError((wxChar *)errBuf.c_str());
584              return false;
585            }
586            // If the current character read in is a '_', we need to check
587            // whether there should be a '\' before it or not
588            if (ch != '_')
589            {
590                buf[bufIndex++] = (wxChar)ch;
591                break;
592            }
593
594            if (checkSyntax)
595            {
596                if (readInVerbatim)
597                {
598                    // There should NOT be a '\' before the '_'
599                    if ((bufIndex > 0 && (buf[bufIndex-1] == '\\')) && (buf[0] != '%'))
600                    {
601//                        wxString errBuf;
602//                        errBuf.Printf(_T("An underscore ('_') was detected at line %lu inside file %s that should NOT have a '\\' before it."),
603//                            LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str());
604//                        OnError((wxChar *)errBuf.c_str());
605                    }
606                }
607                else
608                {
609                    // There should be a '\' before the '_'
610                    if (bufIndex == 0)
611                    {
612                        wxString errBuf;
613                        errBuf.Printf(_T("An underscore ('_') was detected at line %lu inside file %s that may need a '\\' before it."),
614                            LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str());
615                        OnError((wxChar *)errBuf.c_str());
616                    }
617                    else if ((buf[bufIndex-1] != '\\') && (buf[0] != '%') &&  // If it is a comment line, then no warnings
618                        (wxStrncmp(buf, _T("\\input"), 6))) // do not report filenames that have underscores in them
619                    {
620                        wxString errBuf;
621                        errBuf.Printf(_T("An underscore ('_') was detected at line %lu inside file %s that may need a '\\' before it."),
622                            LineNumbers[CurrentInputIndex], (const wxChar*) currentFileName.c_str());
623                        OnError((wxChar *)errBuf.c_str());
624                    }
625                }
626            }
627            buf[bufIndex++] = (wxChar)ch;
628            break;
629        }  // switch
630      }  // else
631    }
632    else
633    {
634      buf[bufIndex] = 0;
635      fclose(Inputs[CurrentInputIndex]);
636      Inputs[CurrentInputIndex] = NULL;
637      if (CurrentInputIndex > 0)
638         ch = ' '; // No real end of file
639      CurrentInputIndex --;
640
641      if (checkCurlyBraces)
642      {
643          if (leftCurly != rightCurly)
644          {
645            wxString errBuf;
646            errBuf.Printf(_T("Curly braces do not match inside file %s\n%lu opens, %lu closes"),
647                          (const wxChar*) currentFileName.c_str(),leftCurly,rightCurly);
648            OnError((wxChar *)errBuf.c_str());
649          }
650          leftCurly = 0;
651          rightCurly = 0;
652      }
653
654      if (readingVerbatim)
655      {
656        readingVerbatim = false;
657        readInVerbatim = false;
658        wxStrcat(buf, _T("\\end{verbatim}\n"));
659        return false;
660      }
661    }
662    if (ch == 10)
663      IncrementLineNumber();
664  }
665  buf[bufIndex] = 0;
666
667  // Strip out comment environment
668  if (wxStrncmp(buf, _T("\\begin{comment}"), 15) == 0)
669  {
670    while (wxStrncmp(buf, _T("\\end{comment}"), 13) != 0)
671      read_a_line(buf);
672    return read_a_line(buf);
673  }
674  // Read a verbatim input file as if it were a verbatim environment
675  else if (wxStrncmp(buf, _T("\\verbatiminput"), 14) == 0)
676  {
677    int wordLen = 14;
678    wxChar *fileName = buf + wordLen + 1;
679
680    int j = bufIndex - 1;
681    buf[j] = 0;
682
683    // thing}\par -- eliminate the \par!
684    if (wxStrncmp((buf + wxStrlen(buf)-5), _T("\\par"), 4) == 0)
685    {
686      j -= 5;
687      buf[j] = 0;
688    }
689
690    if (buf[j-1] == '}')
691        buf[j-1] = 0; // Ignore final brace
692
693    wxString actualFile = TexPathList.FindValidPath(fileName);
694    currentFileName = actualFile;
695    if (actualFile.empty())
696    {
697      wxString errBuf;
698      errBuf.Printf(_T("Could not find file: %s"),fileName);
699      OnError((wxChar *)errBuf.c_str());
700    }
701    else
702    {
703      wxString informStr;
704      informStr.Printf(_T("Processing: %s"),actualFile.c_str());
705      OnInform((wxChar *)informStr.c_str());
706      CurrentInputIndex ++;
707
708      Inputs[CurrentInputIndex] = wxFopen(actualFile, _T("r"));
709      LineNumbers[CurrentInputIndex] = 1;
710      if (FileNames[CurrentInputIndex])
711        delete[] FileNames[CurrentInputIndex];
712      FileNames[CurrentInputIndex] = copystring(actualFile);
713
714      if (!Inputs[CurrentInputIndex])
715      {
716        CurrentInputIndex --;
717        OnError(_T("Could not open verbatiminput file."));
718      }
719      else
720      {
721        readingVerbatim = true;
722        readInVerbatim = true;
723        wxStrcpy(buf, _T("\\begin{verbatim}\n"));
724        return false;
725      }
726    }
727    return false;
728  }
729  else if (wxStrncmp(buf, _T("\\input"), 6) == 0 || wxStrncmp(buf, _T("\\helpinput"), 10) == 0 ||
730      wxStrncmp(buf, _T("\\include"), 8) == 0)
731  {
732    int wordLen;
733    if (wxStrncmp(buf, _T("\\input"), 6) == 0)
734      wordLen = 6;
735    else
736    if (wxStrncmp(buf, _T("\\include"), 8) == 0)
737      wordLen = 8;
738    else
739      wordLen = 10;
740
741    wxChar *fileName = buf + wordLen + 1;
742
743    int j = bufIndex - 1;
744    buf[j] = 0;
745
746    // \input{thing}\par -- eliminate the \par!
747//    if (wxStrncmp((buf + wxStrlen(buf)-5), "\\par", 4) == 0)
748    if (wxStrncmp((buf + wxStrlen(buf)-4), _T("\\par"), 4) == 0) // Bug fix 8/2/95 Ulrich Leodolter
749    {
750//      j -= 5;
751      j -= 4; // Ditto
752      buf[j] = 0;
753    }
754
755    if (buf[j-1] == _T('}'))
756        buf[j-1] = 0; // Ignore final brace
757
758    // Remove backslashes from name
759    wxString fileNameStr(fileName);
760    fileNameStr.Replace(_T("\\"), _T(""));
761
762    // Ignore some types of input files (e.g. macro definition files)
763    wxChar *fileOnly = wxFileNameFromPath((wxChar*) (const wxChar*) fileNameStr);
764    currentFileName = fileOnly;
765    if (IgnorableInputFiles.Member(fileOnly))
766      return read_a_line(buf);
767
768    wxString actualFile = TexPathList.FindValidPath(fileNameStr);
769    if (actualFile.empty())
770    {
771      wxChar buf2[400];
772      wxSnprintf(buf2, sizeof(buf2), _T("%s.tex"), fileNameStr.c_str());
773      actualFile = TexPathList.FindValidPath(buf2);
774    }
775    currentFileName = actualFile;
776
777    if (actualFile.empty())
778    {
779      wxString errBuf;
780      errBuf.Printf(_T("Could not find file: %s"),fileName);
781      OnError((wxChar *)errBuf.c_str());
782    }
783    else
784    {
785      // Ensure that if this file includes another,
786      // then we look in the same directory as this one.
787      TexPathList.EnsureFileAccessible(actualFile);
788
789      wxString informStr;
790      informStr.Printf(_T("Processing: %s"),actualFile.c_str());
791      OnInform((wxChar *)informStr.c_str());
792      CurrentInputIndex ++;
793
794      Inputs[CurrentInputIndex] = wxFopen(actualFile, _T("r"));
795      LineNumbers[CurrentInputIndex] = 1;
796      if (FileNames[CurrentInputIndex])
797        delete[] FileNames[CurrentInputIndex];
798      FileNames[CurrentInputIndex] = copystring(actualFile);
799
800      if (!Inputs[CurrentInputIndex])
801      {
802        wxString errBuf;
803        errBuf.Printf(_T("Could not open include file %s"), (const wxChar*) actualFile);
804        CurrentInputIndex --;
805        OnError((wxChar *)errBuf.c_str());
806      }
807    }
808    bool succ = read_a_line(buf);
809    return succ;
810  }
811
812  if (checkSyntax)
813  {
814      wxString bufStr = buf;
815      for (int index=0; !syntaxTokens[index].empty(); index++)
816      {
817          size_t pos = bufStr.find(syntaxTokens[index]);
818          if (pos != wxString::npos && pos != 0)
819          {
820              size_t commentStart = bufStr.find(_T("%"));
821              if (commentStart == wxString::npos || commentStart > pos)
822              {
823                  wxString errBuf;
824                  if (syntaxTokens[index] == _T("\\verb"))
825                  {
826                      errBuf.Printf(_T("'%s$....$' was detected at line %lu inside file %s.  Please replace this form with \\tt{....}"),
827                                    syntaxTokens[index].c_str(),
828                                    LineNumbers[CurrentInputIndex],
829                                    currentFileName.c_str());
830                  }
831                  else
832                  {
833                      errBuf.Printf(_T("'%s' was detected at line %lu inside file %s that is not the only text on the line, starting at column one."),
834                                    syntaxTokens[index].c_str(),
835                                    LineNumbers[CurrentInputIndex],
836                                    currentFileName.c_str());
837                  }
838                  OnError((wxChar *)errBuf.c_str());
839              }
840          }
841      }
842  }  // checkSyntax
843
844  if (wxStrncmp(buf, _T("\\begin{verbatim}"), 16) == 0 ||
845      wxStrncmp(buf, _T("\\begin{toocomplex}"), 18) == 0)
846    readInVerbatim = true;
847  else if (wxStrncmp(buf, _T("\\end{verbatim}"), 14) == 0 ||
848           wxStrncmp(buf, _T("\\end{toocomplex}"), 16) == 0)
849    readInVerbatim = false;
850
851  if (checkCurlyBraces)
852  {
853      if (ch == EOF && leftCurly != rightCurly)
854      {
855        wxString errBuf;
856        errBuf.Printf(_T("Curly braces do not match inside file %s\n%lu opens, %lu closes"),
857            (const wxChar*) currentFileName.c_str(),leftCurly,rightCurly);
858        OnError((wxChar *)errBuf.c_str());
859      }
860  }
861
862  return (ch == EOF);
863}  // read_a_line
864
865/*
866 * Parse newcommand
867 *
868 */
869
870bool ParseNewCommand(wxChar *buffer, int *pos)
871{
872  if ((wxStrncmp((buffer+(*pos)), _T("newcommand"), 10) == 0) ||
873      (wxStrncmp((buffer+(*pos)), _T("renewcommand"), 12) == 0))
874  {
875    if (wxStrncmp((buffer+(*pos)), _T("newcommand"), 10) == 0)
876      *pos = *pos + 12;
877    else
878      *pos = *pos + 14;
879
880    wxChar commandName[100];
881    wxChar commandValue[1000];
882    int noArgs = 0;
883    int i = 0;
884    while (buffer[*pos] != _T('}') && (buffer[*pos] != 0))
885    {
886      commandName[i] = buffer[*pos];
887      *pos += 1;
888      i ++;
889    }
890    commandName[i] = 0;
891    i = 0;
892    *pos += 1;
893    if (buffer[*pos] == _T('['))
894    {
895      *pos += 1;
896      noArgs = (int)(buffer[*pos]) - 48;
897      *pos += 2; // read past argument and '['
898    }
899    bool end = false;
900    int braceCount = 0;
901    while (!end)
902    {
903      wxChar ch = buffer[*pos];
904      if (ch == _T('{'))
905        braceCount ++;
906      else if (ch == _T('}'))
907      {
908        braceCount --;
909        if (braceCount == 0)
910          end = true;
911      }
912      else if (ch == 0)
913      {
914        end = !read_a_line(buffer);
915        wxUnusedVar(end);
916        *pos = 0;
917        break;
918      }
919      commandValue[i] = ch;
920      i ++;
921      *pos += 1;
922    }
923    commandValue[i] = 0;
924
925    CustomMacro *macro = new CustomMacro(commandName, noArgs, NULL);
926    if (wxStrlen(commandValue) > 0)
927      macro->macroBody = copystring(commandValue);
928    if (!CustomMacroList.Find(commandName))
929    {
930      CustomMacroList.Append(commandName, macro);
931      AddMacroDef(ltCUSTOM_MACRO, commandName, noArgs);
932    }
933    return true;
934  }
935  else return false;
936}
937
938void MacroError(wxChar *buffer)
939{
940  wxString errBuf;
941  wxChar macroBuf[30];
942  macroBuf[0] = wxT('\\');
943  int i = 1;
944  wxChar ch;
945  while (((i < 30) && (ch = buffer[i-1]) != wxT('\n')) && (ch != 0))
946  {
947    macroBuf[i] = ch;
948    i ++;
949  }
950  macroBuf[i] = 0;
951  if (i > 20)
952  {
953    macroBuf[20] = wxT('.');
954    macroBuf[21] = wxT('.');
955    macroBuf[22] = wxT('.');
956    macroBuf[23] = 0;
957  }
958
959  errBuf.Printf(_T("Could not find macro: %s at line %d, file %s"),
960             macroBuf, (int)(LineNumbers[CurrentInputIndex]-1), FileNames[CurrentInputIndex]);
961  OnError((wxChar *)errBuf.c_str());
962
963  if (wxStrcmp(macroBuf,_T("\\end{document}")) == 0)
964  {
965      OnInform( _T("Halted build due to unrecoverable error.") );
966      stopRunning = true;
967  }
968}
969
970/*
971 * Parse an argument.
972 * 'environment' specifies the name of the macro IFF if we're looking for the end
973 * of an environment, e.g. \end{itemize}. Otherwise it's NULL.
974 * 'parseToBrace' is true if the argument should extend to the next right brace,
975 * e.g. in {\bf an argument} as opposed to \vskip 30pt
976 *
977 */
978int ParseArg(TexChunk *thisArg, wxList& children, wxChar *buffer, int pos, wxChar *environment, bool parseToBrace, TexChunk *customMacroArgs)
979{
980  Tex2RTFYield();
981  if (stopRunning) return pos;
982
983  bool eof = false;
984  BigBuffer[0] = 0;
985  int buf_ptr = 0;
986  int len;
987
988/*
989
990  // Consume leading brace or square bracket, but ONLY if not following
991  // a space, because this could be e.g. {\large {\bf thing}} where {\bf thing}
992  // is the argument of \large AS WELL as being a block in its
993  // own right.
994  if (!environment)
995  {
996    if ((pos > 0) && (buffer[pos-1] != ' ') && buffer[pos] == '{')
997      pos ++;
998    else
999
1000    if ((pos > 0) && (buffer[pos-1] != ' ') && (buffer[pos] == '[' || buffer[pos] == '('))
1001    {
1002      isOptional = true;
1003      pos ++;
1004    }
1005    else if ((pos > 1) && (buffer[pos-1] != ' ') && (buffer[pos+1] == '[' || buffer[pos+1] == '('))
1006    {
1007      isOptional = true;
1008      pos += 2;
1009    }
1010  }
1011*/
1012
1013  // If not parsing to brace, just read the next word
1014  // (e.g. \vskip 20pt)
1015  if (!parseToBrace)
1016  {
1017    int ch = buffer[pos];
1018    while (!eof && ch != 13 && ch != 32 && ch != 10 &&
1019           ch != 0 && ch != '{')
1020    {
1021      BigBuffer[buf_ptr] = (wxChar)ch;
1022      buf_ptr ++;
1023      pos ++;
1024      ch = buffer[pos];
1025    }
1026    if (buf_ptr > 0)
1027    {
1028      TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1029      BigBuffer[buf_ptr] = 0;
1030      chunk->value = copystring(BigBuffer);
1031      children.Append((wxObject *)chunk);
1032    }
1033    return pos;
1034  }
1035
1036  while (!eof)
1037  {
1038    len = wxStrlen(buffer);
1039    if (pos >= len)
1040    {
1041      if (customMacroArgs) return 0;
1042
1043      eof = read_a_line(buffer);
1044      pos = 0;
1045      // Check for verbatim (or toocomplex, which comes to the same thing)
1046      wxString bufStr = buffer;
1047//      if (bufStr.find("\\begin{verbatim}") != wxString::npos ||
1048//          bufStr.find("\\begin{toocomplex}") != wxString::npos)
1049      if (wxStrncmp(buffer, _T("\\begin{verbatim}"), 16) == 0 ||
1050          wxStrncmp(buffer, _T("\\begin{toocomplex}"), 18) == 0)
1051      {
1052        if (buf_ptr > 0)
1053        {
1054          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1055          BigBuffer[buf_ptr] = 0;
1056          chunk->value = copystring(BigBuffer);
1057          children.Append((wxObject *)chunk);
1058        }
1059        BigBuffer[0] = 0;
1060        buf_ptr = 0;
1061
1062        eof = read_a_line(buffer);
1063        while (!eof && (wxStrncmp(buffer, _T("\\end{verbatim}"), 14) != 0) &&
1064                       (wxStrncmp(buffer, _T("\\end{toocomplex}"), 16) != 0)
1065               )
1066        {
1067          wxStrcat(BigBuffer, buffer);
1068          buf_ptr += wxStrlen(buffer);
1069          eof = read_a_line(buffer);
1070        }
1071        eof = read_a_line(buffer);
1072        buf_ptr = 0;
1073
1074        TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, VerbatimMacroDef);
1075        chunk->no_args = 1;
1076        chunk->macroId = ltVERBATIM;
1077        TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, VerbatimMacroDef);
1078        arg->argn = 1;
1079        arg->macroId = ltVERBATIM;
1080        TexChunk *str = new TexChunk(CHUNK_TYPE_STRING);
1081        str->value = copystring(BigBuffer);
1082
1083        children.Append((wxObject *)chunk);
1084        chunk->children.Append((wxObject *)arg);
1085        arg->children.Append((wxObject *)str);
1086
1087        // Also want to include the following newline (is always a newline
1088        // after a verbatim): EXCEPT in HTML
1089        if (convertMode != TEX_HTML)
1090        {
1091          TexMacroDef *parDef = (TexMacroDef *)MacroDefs.Get(_T("\\"));
1092          TexChunk *parChunk = new TexChunk(CHUNK_TYPE_MACRO, parDef);
1093          parChunk->no_args = 0;
1094          parChunk->macroId = ltBACKSLASHCHAR;
1095          children.Append((wxObject *)parChunk);
1096        }
1097      }
1098    }
1099
1100    wxChar wxCh = buffer[pos];
1101    // End of optional argument -- pretend it's right brace for simplicity
1102    if (thisArg->optional && (wxCh == _T(']')))
1103      wxCh = _T('}');
1104
1105    switch (wxCh)
1106    {
1107      case 0:
1108      case _T('}'):  // End of argument
1109      {
1110        if (buf_ptr > 0)
1111        {
1112          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1113          BigBuffer[buf_ptr] = 0;
1114          chunk->value = copystring(BigBuffer);
1115          children.Append((wxObject *)chunk);
1116        }
1117        if (wxCh == _T('}')) pos ++;
1118        return pos;
1119      }
1120      case _T('\\'):
1121      {
1122        if (buf_ptr > 0)  // Finish off the string we've read so far
1123        {
1124          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1125          BigBuffer[buf_ptr] = 0;
1126          buf_ptr = 0;
1127          chunk->value = copystring(BigBuffer);
1128          children.Append((wxObject *)chunk);
1129        }
1130        pos ++;
1131
1132        // Try matching \end{environment}
1133        if (environment && FindEndEnvironment(buffer, &pos, environment))
1134        {
1135          // Eliminate newline after an \end{} if possible
1136          if (buffer[pos] == 13)
1137          {
1138            pos ++;
1139            if (buffer[pos] == 10)
1140              pos ++;
1141          }
1142          return pos;
1143        }
1144
1145        if (ParseNewCommand(buffer, &pos))
1146          break;
1147
1148        if (wxStrncmp(buffer+pos, _T("special"), 7) == 0)
1149        {
1150          pos += 7;
1151
1152          // Discard {
1153          pos ++;
1154          int noBraces = 1;
1155
1156          wxTex2RTFBuffer[0] = 0;
1157          int i = 0;
1158          bool end = false;
1159          while (!end)
1160          {
1161            wxChar ch = buffer[pos];
1162            if (ch == _T('}'))
1163            {
1164              noBraces --;
1165              if (noBraces == 0)
1166              {
1167                wxTex2RTFBuffer[i] = 0;
1168                end = true;
1169              }
1170              else
1171              {
1172                wxTex2RTFBuffer[i] = _T('}');
1173                i ++;
1174              }
1175              pos ++;
1176            }
1177            else if (ch == _T('{'))
1178            {
1179              wxTex2RTFBuffer[i] = _T('{');
1180              i ++;
1181              pos ++;
1182            }
1183            else if (ch == _T('\\') && buffer[pos+1] == _T('}'))
1184            {
1185              wxTex2RTFBuffer[i] = _T('}');
1186              pos += 2;
1187              i++;
1188            }
1189            else if (ch == _T('\\') && buffer[pos+1] == _T('{'))
1190            {
1191              wxTex2RTFBuffer[i] = _T('{');
1192              pos += 2;
1193              i++;
1194            }
1195            else
1196            {
1197              wxTex2RTFBuffer[i] = ch;
1198              pos ++;
1199              i ++;
1200              if (ch == 0)
1201                end = true;
1202            }
1203          }
1204          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1205          chunk->no_args = 1;
1206          chunk->macroId = ltSPECIAL;
1207          TexMacroDef *specialDef = (TexMacroDef *)MacroDefs.Get(_T("special"));
1208          chunk->def = specialDef;
1209          TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, specialDef);
1210          chunk->children.Append((wxObject *)arg);
1211          arg->argn = 1;
1212          arg->macroId = chunk->macroId;
1213
1214          // The value in the first argument.
1215          TexChunk *argValue = new TexChunk(CHUNK_TYPE_STRING);
1216          arg->children.Append((wxObject *)argValue);
1217          argValue->argn = 1;
1218          argValue->value = copystring(wxTex2RTFBuffer);
1219
1220          children.Append((wxObject *)chunk);
1221        }
1222        else if (wxStrncmp(buffer+pos, _T("verb"), 4) == 0)
1223        {
1224          pos += 4;
1225          if (buffer[pos] == _T('*'))
1226            pos ++;
1227
1228          // Find the delimiter character
1229          wxChar ch = buffer[pos];
1230          pos ++;
1231          // Now at start of verbatim text
1232          int j = pos;
1233          while ((buffer[pos] != ch) && buffer[pos] != 0)
1234            pos ++;
1235          wxChar *val = new wxChar[pos - j + 1];
1236          int i;
1237          for (i = j; i < pos; i++)
1238          {
1239            val[i-j] = buffer[i];
1240          }
1241          val[i-j] = 0;
1242
1243          pos ++;
1244
1245          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1246          chunk->no_args = 1;
1247          chunk->macroId = ltVERB;
1248          TexMacroDef *verbDef = (TexMacroDef *)MacroDefs.Get(_T("verb"));
1249          chunk->def = verbDef;
1250          TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, verbDef);
1251          chunk->children.Append((wxObject *)arg);
1252          arg->argn = 1;
1253          arg->macroId = chunk->macroId;
1254
1255          // The value in the first argument.
1256          TexChunk *argValue = new TexChunk(CHUNK_TYPE_STRING);
1257          arg->children.Append((wxObject *)argValue);
1258          argValue->argn = 1;
1259          argValue->value = val;
1260
1261          children.Append((wxObject *)chunk);
1262        }
1263        else
1264        {
1265          wxChar *env = NULL;
1266          bool tmpParseToBrace = true;
1267          TexMacroDef *def = MatchMacro(buffer, &pos, &env, &tmpParseToBrace);
1268          if (def)
1269          {
1270          CustomMacro *customMacro = FindCustomMacro(def->name);
1271
1272          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, def);
1273
1274          chunk->no_args = def->no_args;
1275//          chunk->name = copystring(def->name);
1276          chunk->macroId = def->macroId;
1277
1278          if  (!customMacro)
1279            children.Append((wxObject *)chunk);
1280
1281          // Eliminate newline after a \begin{} or a \\ if possible
1282          if ((env || wxStrcmp(def->name, _T("\\")) == 0) && (buffer[pos] == 13))
1283          {
1284              pos ++;
1285              if (buffer[pos] == 10)
1286                pos ++;
1287          }
1288
1289          pos = ParseMacroBody(def->name,
1290                               chunk, chunk->no_args,
1291                               buffer,
1292                               pos,
1293                               env,
1294                               tmpParseToBrace,
1295                               customMacroArgs);
1296
1297          // If custom macro, parse the body substituting the above found args.
1298          if (customMacro)
1299          {
1300            if (customMacro->macroBody)
1301            {
1302              wxChar macroBuf[300];
1303//              wxStrcpy(macroBuf, _T("{"));
1304              wxStrcpy(macroBuf, customMacro->macroBody);
1305              wxStrcat(macroBuf, _T("}"));
1306              ParseArg(thisArg, children, macroBuf, 0, NULL, true, chunk);
1307            }
1308
1309//            delete chunk; // Might delete children
1310          }
1311        }
1312        else
1313        {
1314          MacroError(buffer+pos);
1315        }
1316        }
1317        break;
1318      }
1319      // Parse constructs like {\bf thing} as if they were
1320      // \bf{thing}
1321      case _T('{'):
1322      {
1323        pos ++;
1324        if (buffer[pos] == _T('\\'))
1325        {
1326          if (buf_ptr > 0)
1327          {
1328            TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1329            BigBuffer[buf_ptr] = 0;
1330            buf_ptr = 0;
1331            chunk->value = copystring(BigBuffer);
1332            children.Append((wxObject *)chunk);
1333          }
1334          pos ++;
1335
1336          wxChar *env;
1337          bool tmpParseToBrace;
1338          TexMacroDef *def = MatchMacro(buffer, &pos, &env, &tmpParseToBrace);
1339          if (def)
1340          {
1341            CustomMacro *customMacro = FindCustomMacro(def->name);
1342
1343            TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, def);
1344            chunk->no_args = def->no_args;
1345//            chunk->name = copystring(def->name);
1346            chunk->macroId = def->macroId;
1347            if (!customMacro)
1348              children.Append((wxObject *)chunk);
1349
1350            pos = ParseMacroBody(def->name, chunk, chunk->no_args,
1351                       buffer, pos, NULL, true, customMacroArgs);
1352
1353            // If custom macro, parse the body substituting the above found args.
1354            if (customMacro)
1355            {
1356              if (customMacro->macroBody)
1357              {
1358                wxChar macroBuf[300];
1359//                wxStrcpy(macroBuf, _T("{"));
1360                wxStrcpy(macroBuf, customMacro->macroBody);
1361                wxStrcat(macroBuf, _T("}"));
1362                ParseArg(thisArg, children, macroBuf, 0, NULL, true, chunk);
1363              }
1364
1365//            delete chunk; // Might delete children
1366        }
1367          }
1368          else
1369          {
1370            MacroError(buffer+pos);
1371          }
1372        }
1373        else
1374        {
1375         /*
1376          * If all else fails, we assume that we have
1377          * a pair of braces on their own, so return a `dummy' macro
1378          * definition with just one argument to parse.
1379          */
1380          if (!SoloBlockDef)
1381          {
1382            SoloBlockDef = new TexMacroDef(ltSOLO_BLOCK, _T("solo block"), 1, false);
1383          }
1384          // Save text so far
1385          if (buf_ptr > 0)
1386          {
1387            TexChunk *chunk1 = new TexChunk(CHUNK_TYPE_STRING);
1388            BigBuffer[buf_ptr] = 0;
1389            buf_ptr = 0;
1390            chunk1->value = copystring(BigBuffer);
1391            children.Append((wxObject *)chunk1);
1392          }
1393          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, SoloBlockDef);
1394          chunk->no_args = SoloBlockDef->no_args;
1395//          chunk->name = copystring(SoloBlockDef->name);
1396          chunk->macroId = SoloBlockDef->macroId;
1397          children.Append((wxObject *)chunk);
1398
1399          TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, SoloBlockDef);
1400
1401          chunk->children.Append((wxObject *)arg);
1402//          arg->name = copystring(SoloBlockDef->name);
1403          arg->argn = 1;
1404          arg->macroId = chunk->macroId;
1405
1406          pos = ParseArg(arg, arg->children, buffer, pos, NULL, true, customMacroArgs);
1407        }
1408        break;
1409      }
1410      case _T('$'):
1411      {
1412        if (buf_ptr > 0)
1413        {
1414          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1415          BigBuffer[buf_ptr] = 0;
1416          buf_ptr = 0;
1417          chunk->value = copystring(BigBuffer);
1418          children.Append((wxObject *)chunk);
1419        }
1420
1421        pos ++;
1422
1423        if (buffer[pos] == _T('$'))
1424        {
1425          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1426          chunk->no_args = 0;
1427//          chunk->name = copystring(_T("$$"));
1428          chunk->macroId = ltSPECIALDOUBLEDOLLAR;
1429          children.Append((wxObject *)chunk);
1430          pos ++;
1431        }
1432        else
1433        {
1434          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1435          chunk->no_args = 0;
1436//          chunk->name = copystring(_T("_$"));
1437          chunk->macroId = ltSPECIALDOLLAR;
1438          children.Append((wxObject *)chunk);
1439        }
1440        break;
1441      }
1442      case _T('~'):
1443      {
1444        if (buf_ptr > 0)
1445        {
1446          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1447          BigBuffer[buf_ptr] = 0;
1448          buf_ptr = 0;
1449          chunk->value = copystring(BigBuffer);
1450          children.Append((wxObject *)chunk);
1451        }
1452
1453        pos ++;
1454        TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1455        chunk->no_args = 0;
1456//        chunk->name = copystring(_T("_~"));
1457        chunk->macroId = ltSPECIALTILDE;
1458        children.Append((wxObject *)chunk);
1459        break;
1460      }
1461      case _T('#'): // Either treat as a special TeX character or as a macro arg
1462      {
1463        if (buf_ptr > 0)
1464        {
1465          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1466          BigBuffer[buf_ptr] = 0;
1467          buf_ptr = 0;
1468          chunk->value = copystring(BigBuffer);
1469          children.Append((wxObject *)chunk);
1470        }
1471
1472        pos ++;
1473        if (!customMacroArgs)
1474        {
1475          TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1476          chunk->no_args = 0;
1477//          chunk->name = copystring(_T("_#"));
1478          chunk->macroId = ltSPECIALHASH;
1479          children.Append((wxObject *)chunk);
1480        }
1481        else
1482        {
1483          if (isdigit(buffer[pos]))
1484          {
1485            int n = buffer[pos] - 48;
1486            pos ++;
1487            wxNode *node = customMacroArgs->children.Item(n-1);
1488            if (node)
1489            {
1490              TexChunk *argChunk = (TexChunk *)node->GetData();
1491              children.Append((wxObject *)new TexChunk(*argChunk));
1492            }
1493          }
1494        }
1495        break;
1496      }
1497      case _T('&'):
1498      {
1499        // Remove white space before and after the ampersand,
1500        // since this is probably a table column separator with
1501        // some convenient -- but useless -- white space in the text.
1502        while ((buf_ptr > 0) && ((BigBuffer[buf_ptr-1] == _T(' ')) || (BigBuffer[buf_ptr-1] == 9)))
1503          buf_ptr --;
1504
1505        if (buf_ptr > 0)
1506        {
1507          TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
1508          BigBuffer[buf_ptr] = 0;
1509          buf_ptr = 0;
1510          chunk->value = copystring(BigBuffer);
1511          children.Append((wxObject *)chunk);
1512        }
1513
1514        pos ++;
1515
1516        while (buffer[pos] == _T(' ') || buffer[pos] == 9)
1517          pos ++;
1518
1519        TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
1520        chunk->no_args = 0;
1521//        chunk->name = copystring(_T("_&"));
1522        chunk->macroId = ltSPECIALAMPERSAND;
1523        children.Append((wxObject *)chunk);
1524        break;
1525      }
1526      // Eliminate end-of-line comment
1527      case _T('%'):
1528      {
1529        wxCh = buffer[pos];
1530        while (wxCh != 10 && wxCh != 13 && wxCh != 0)
1531        {
1532          pos ++;
1533          wxCh = buffer[pos];
1534        }
1535        if (buffer[pos] == 10 || buffer[pos] == 13)
1536        {
1537          pos ++;
1538          if (buffer[pos] == 10) pos ++; // Eliminate newline following DOS line feed
1539        }
1540        break;
1541      }
1542      // Eliminate tab
1543      case 9:
1544      {
1545        BigBuffer[buf_ptr] = _T(' ');
1546        BigBuffer[buf_ptr+1] = 0;
1547        buf_ptr ++;
1548        pos ++;
1549        break;
1550      }
1551      default:
1552      {
1553        BigBuffer[buf_ptr] = wxCh;
1554        BigBuffer[buf_ptr+1] = 0;
1555        buf_ptr ++;
1556        pos ++;
1557        break;
1558      }
1559    }
1560  }
1561  return pos;
1562}
1563
1564/*
1565 * Consume as many arguments as the macro definition specifies
1566 *
1567 */
1568
1569int ParseMacroBody(const wxChar *WXUNUSED(macro_name), TexChunk *parent,
1570                   int no_args, wxChar *buffer, int pos,
1571                   wxChar *environment, bool parseToBrace,
1572                   TexChunk *customMacroArgs)
1573{
1574  Tex2RTFYield();
1575  if (stopRunning) return pos;
1576
1577  // Check for a first optional argument
1578  if (buffer[pos] == ' ' && buffer[pos+1] == '[')
1579  {
1580    // Fool following code into thinking that this is definitely
1581    // an optional first argument. (If a space before a non-first argument,
1582    // [ is interpreted as a [, not an optional argument.)
1583    buffer[pos] = '!';
1584    pos ++;
1585    no_args ++;
1586  }
1587  else
1588    if (buffer[pos] == '[')
1589      no_args ++;
1590
1591  int maxArgs = 0;
1592
1593  int i;
1594  for (i = 0; i < no_args; i++)
1595  {
1596    maxArgs ++;
1597    TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, parent->def);
1598
1599    parent->children.Append((wxObject *)arg);
1600//    arg->name = copystring(macro_name);
1601    arg->argn = maxArgs;
1602    arg->macroId = parent->macroId;
1603
1604    // To parse the first arg of a 2 arg \begin{thing}{arg} ... \end{thing}
1605    // have to fool parser into thinking this is a regular kind of block.
1606    wxChar *actualEnv;
1607    if ((no_args == 2) && (i == 0))
1608      actualEnv = NULL;
1609    else
1610      actualEnv = environment;
1611
1612    bool isOptional = false;
1613
1614    // Remove the first { of the argument so it doesn't get recognized as { ... }
1615//    EatWhiteSpace(buffer, &pos);
1616    if (!actualEnv)
1617    {
1618      // The reason for these tests is to not consume braces that don't
1619      // belong to this macro.
1620      // E.g. {\bf {\small thing}}
1621      if ((pos > 0) && (buffer[pos-1] != ' ') && buffer[pos] == '{')
1622        pos ++;
1623      else
1624      if ((pos > 0) && (buffer[pos-1] != ' ') && (buffer[pos] == '['))
1625      {
1626        isOptional = true;
1627        pos ++;
1628      }
1629      else if ((pos > 1) && (buffer[pos-1] != ' ') && (buffer[pos+1] == '['))
1630      {
1631        isOptional = true;
1632        pos += 2;
1633      }
1634      else if (i > 0)
1635      {
1636        wxString errBuf;
1637        wxString tmpBuffer(buffer);
1638        if (tmpBuffer.length() > 4)
1639        {
1640            if (tmpBuffer.Right(4) == _T("\\par"))
1641                tmpBuffer = tmpBuffer.Mid(0,tmpBuffer.length()-4);
1642        }
1643        errBuf.Printf(_T("Missing macro argument in the line:\n\t%s\n"),tmpBuffer.c_str());
1644        OnError((wxChar *)errBuf.c_str());
1645      }
1646
1647    }
1648    arg->optional = isOptional;
1649
1650    pos = ParseArg(arg, arg->children, buffer, pos, actualEnv, parseToBrace, customMacroArgs);
1651
1652    // If we've encountered an OPTIONAL argument, go another time around
1653    // the loop, because we've got more than we thought.
1654    // Hopefully optional args don't occur at the end of a macro use
1655    // or we might miss it.
1656    // Don't increment no of times round loop if the first optional arg
1657    // -- we already did it before the loop.
1658    if (arg->optional && (i > 0))
1659      i --;
1660  }
1661  parent->no_args = maxArgs;
1662
1663  // Tell each argument how many args there are (useful when processing an arg)
1664  wxNode *node = parent->children.GetFirst();
1665  while (node)
1666  {
1667    TexChunk *chunk = (TexChunk *)node->GetData();
1668    chunk->no_args = maxArgs;
1669    node = node->GetNext();
1670  }
1671  return pos;
1672}
1673
1674bool TexLoadFile(const wxString& filename)
1675{
1676    static wxChar *line_buffer;
1677    stopRunning = false;
1678    wxStrcpy(TexFileRoot, filename);
1679    StripExtension(TexFileRoot);
1680    wxSnprintf(TexBibName, 300, _T("%s.bb"), TexFileRoot);
1681    wxSnprintf(TexTmpBibName, 300, _T("%s.bb1"), TexFileRoot);
1682
1683    TexPathList.EnsureFileAccessible(filename);
1684
1685    if (line_buffer)
1686        delete line_buffer;
1687
1688    line_buffer = new wxChar[MAX_LINE_BUFFER_SIZE];
1689
1690    Inputs[0] = wxFopen(filename, _T("r"));
1691    LineNumbers[0] = 1;
1692    FileNames[0] = copystring(filename);
1693    if (Inputs[0])
1694    {
1695        read_a_line(line_buffer);
1696        ParseMacroBody(_T("toplevel"), TopLevel, 1, line_buffer, 0, NULL, true);
1697        if (Inputs[0]) fclose(Inputs[0]);
1698        return true;
1699    }
1700
1701    return false;
1702}
1703
1704TexMacroDef::TexMacroDef(int the_id, const wxChar *the_name, int n, bool ig, bool forbidLevel)
1705{
1706  name = copystring(the_name);
1707  no_args = n;
1708  ignore = ig;
1709  macroId = the_id;
1710  forbidden = forbidLevel;
1711}
1712
1713TexMacroDef::~TexMacroDef(void)
1714{
1715  if (name) delete[] name;
1716}
1717
1718TexChunk::TexChunk(int the_type, TexMacroDef *the_def)
1719{
1720  type = the_type;
1721  no_args = 0;
1722  argn = 0;
1723//  name = NULL;
1724  def = the_def;
1725  macroId = 0;
1726  value = NULL;
1727  optional = false;
1728}
1729
1730TexChunk::TexChunk(TexChunk& toCopy)
1731{
1732  type = toCopy.type;
1733  no_args = toCopy.no_args;
1734  argn = toCopy.argn;
1735  macroId = toCopy.macroId;
1736
1737//  if (toCopy.name)
1738//    name = copystring(toCopy.name);
1739//  else
1740//    name = NULL;
1741  def = toCopy.def;
1742
1743  if (toCopy.value)
1744    value = copystring(toCopy.value);
1745  else
1746    value = NULL;
1747
1748  optional = toCopy.optional;
1749  wxNode *node = toCopy.children.GetFirst();
1750  while (node)
1751  {
1752    TexChunk *child = (TexChunk *)node->GetData();
1753    children.Append((wxObject *)new TexChunk(*child));
1754    node = node->GetNext();
1755  }
1756}
1757
1758TexChunk::~TexChunk(void)
1759{
1760//  if (name) delete[] name;
1761  if (value) delete[] value;
1762  wxNode *node = children.GetFirst();
1763  while (node)
1764  {
1765    TexChunk *child = (TexChunk *)node->GetData();
1766    delete child;
1767    wxNode *next = node->GetNext();
1768    delete node;
1769    node = next;
1770  }
1771}
1772
1773bool IsArgOptional(void)  // Is this argument an optional argument?
1774{
1775  return isArgOptional;
1776}
1777
1778int GetNoArgs(void) // Number of args for this macro
1779{
1780  return noArgs;
1781}
1782
1783/* Gets the text of a chunk on request (must be for small arguments
1784 * only!)
1785 *
1786 */
1787
1788void GetArgData1(TexChunk *chunk)
1789{
1790  switch (chunk->type)
1791  {
1792    case CHUNK_TYPE_MACRO:
1793    {
1794      TexMacroDef *def = chunk->def;
1795      if (def && def->ignore)
1796        return;
1797
1798      if (def && (wxStrcmp(def->name, _T("solo block")) != 0))
1799      {
1800        wxStrcat(currentArgData, _T("\\"));
1801        wxStrcat(currentArgData, def->name);
1802      }
1803
1804      wxNode *node = chunk->children.GetFirst();
1805      while (node)
1806      {
1807        TexChunk *child_chunk = (TexChunk *)node->GetData();
1808        wxStrcat(currentArgData, _T("{"));
1809        GetArgData1(child_chunk);
1810        wxStrcat(currentArgData, _T("}"));
1811        node = node->GetNext();
1812      }
1813      break;
1814    }
1815    case CHUNK_TYPE_ARG:
1816    {
1817      wxNode *node = chunk->children.GetFirst();
1818      while (node)
1819      {
1820        TexChunk *child_chunk = (TexChunk *)node->GetData();
1821        GetArgData1(child_chunk);
1822        node = node->GetNext();
1823      }
1824      break;
1825    }
1826    case CHUNK_TYPE_STRING:
1827    {
1828      if (chunk->value)
1829        wxStrcat(currentArgData, chunk->value);
1830      break;
1831    }
1832  }
1833}
1834
1835wxChar *GetArgData(TexChunk *WXUNUSED(chunk))
1836{
1837  currentArgData[0] = 0;
1838  GetArgData1(currentArgument);
1839  haveArgData = false;
1840  return currentArgData;
1841}
1842
1843wxChar *GetArgData(void)
1844{
1845  if (!haveArgData)
1846  {
1847    currentArgData[0] = 0;
1848    GetArgData1(currentArgument);
1849  }
1850  return currentArgData;
1851}
1852
1853TexChunk *GetArgChunk(void)
1854{
1855  return currentArgument;
1856}
1857
1858TexChunk *GetNextChunk(void)     // Look ahead to the next chunk
1859{
1860  return nextChunk;
1861}
1862
1863TexChunk *GetTopLevelChunk(void)
1864{
1865  return TopLevel;
1866}
1867
1868int GetCurrentColumn(void)
1869{
1870  return currentColumn;
1871}
1872
1873/*
1874 * Traverses document calling functions to allow the client to
1875 * write out the appropriate stuff
1876 */
1877
1878
1879void TraverseFromChunk(TexChunk *chunk, wxNode *thisNode, bool childrenOnly)
1880{
1881  Tex2RTFYield();
1882  if (stopRunning) return;
1883
1884  switch (chunk->type)
1885  {
1886    case CHUNK_TYPE_MACRO:
1887    {
1888      TexMacroDef *def = chunk->def;
1889      if (def && def->ignore)
1890        return;
1891
1892      if (!childrenOnly)
1893        OnMacro(chunk->macroId, chunk->no_args, true);
1894
1895      wxNode *node = chunk->children.GetFirst();
1896      while (node)
1897      {
1898        TexChunk *child_chunk = (TexChunk *)node->GetData();
1899        TraverseFromChunk(child_chunk, node);
1900        node = node->GetNext();
1901      }
1902
1903      if (thisNode && thisNode->GetNext())
1904          nextChunk = (TexChunk *)thisNode->GetNext()->GetData();
1905
1906      if (!childrenOnly)
1907        OnMacro(chunk->macroId, chunk->no_args, false);
1908      break;
1909    }
1910    case CHUNK_TYPE_ARG:
1911    {
1912      currentArgument = chunk;
1913
1914      isArgOptional = chunk->optional;
1915      noArgs = chunk->no_args;
1916
1917      // If OnArgument returns false, don't output.
1918
1919      if (childrenOnly || OnArgument(chunk->macroId, chunk->argn, true))
1920      {
1921        wxNode *node = chunk->children.GetFirst();
1922        while (node)
1923        {
1924          TexChunk *child_chunk = (TexChunk *)node->GetData();
1925          TraverseFromChunk(child_chunk, node);
1926          node = node->GetNext();
1927        }
1928      }
1929
1930      currentArgument = chunk;
1931
1932      if (thisNode && thisNode->GetNext())
1933          nextChunk = (TexChunk *)thisNode->GetNext()->GetData();
1934
1935      isArgOptional = chunk->optional;
1936      noArgs = chunk->no_args;
1937
1938      if (!childrenOnly)
1939        (void)OnArgument(chunk->macroId, chunk->argn, false);
1940      break;
1941    }
1942    case CHUNK_TYPE_STRING:
1943    {
1944      extern int issuedNewParagraph;
1945      extern int forbidResetPar;
1946      if (chunk->value && (forbidResetPar == 0))
1947      {
1948        // If non-whitespace text, we no longer have a new paragraph.
1949        if (issuedNewParagraph && !((chunk->value[0] == 10 || chunk->value[0] == 13 || chunk->value[0] == 32)
1950                                    && chunk->value[1] == 0))
1951        {
1952          issuedNewParagraph = false;
1953        }
1954        TexOutput(chunk->value, true);
1955      }
1956      break;
1957    }
1958  }
1959}
1960
1961void TraverseDocument(void)
1962{
1963  TraverseFromChunk(TopLevel, NULL);
1964}
1965
1966void SetCurrentOutput(FILE *fd)
1967{
1968  CurrentOutput1 = fd;
1969  CurrentOutput2 = NULL;
1970}
1971
1972void SetCurrentOutputs(FILE *fd1, FILE *fd2)
1973{
1974  CurrentOutput1 = fd1;
1975  CurrentOutput2 = fd2;
1976}
1977
1978void AddMacroDef(int the_id, const wxChar *name, int n, bool ignore, bool forbid)
1979{
1980  MacroDefs.Put(name, new TexMacroDef(the_id, name, n, ignore, forbid));
1981}
1982
1983void TexInitialize(int bufSize)
1984{
1985  InitialiseColourTable();
1986#ifdef __WXMSW__
1987  TexPathList.AddEnvList(_T("TEXINPUT"));
1988#endif
1989#ifdef __UNIX__
1990  TexPathList.AddEnvList(_T("TEXINPUTS"));
1991#endif
1992  int i;
1993  for (i = 0; i < 15; i++)
1994  {
1995    Inputs[i] = NULL;
1996    LineNumbers[i] = 1;
1997    FileNames[i] = NULL;
1998  }
1999
2000  IgnorableInputFiles.Add(_T("psbox.tex"));
2001  BigBuffer = new wxChar[(bufSize*1000)];
2002  currentArgData = new wxChar[2000];
2003  TexFileRoot = new wxChar[300];
2004  TexBibName = new wxChar[300];
2005  TexTmpBibName = new wxChar[300];
2006  AddMacroDef(ltTOPLEVEL, _T("toplevel"), 1);
2007  TopLevel = new TexChunk(CHUNK_TYPE_MACRO);
2008//  TopLevel->name = copystring(_T("toplevel"));
2009  TopLevel->macroId = ltTOPLEVEL;
2010  TopLevel->no_args = 1;
2011  VerbatimMacroDef = (TexMacroDef *)MacroDefs.Get(_T("verbatim"));
2012}
2013
2014void TexCleanUp(void)
2015{
2016  int i;
2017  for (i = 0; i < 15; i++)
2018    Inputs[i] = NULL;
2019
2020  chapterNo = 0;
2021  sectionNo = 0;
2022  subsectionNo = 0;
2023  subsubsectionNo = 0;
2024  figureNo = 0;
2025
2026  CurrentOutput1 = NULL;
2027  CurrentOutput2 = NULL;
2028  CurrentInputIndex = 0;
2029  haveArgData = false;
2030  noArgs = 0;
2031
2032  if (TopLevel)
2033    delete TopLevel;
2034  TopLevel = new TexChunk(CHUNK_TYPE_MACRO);
2035//  TopLevel->name = copystring(_T("toplevel"));
2036  TopLevel->macroId = ltTOPLEVEL;
2037  TopLevel->no_args = 1;
2038
2039  DocumentTitle = NULL;
2040  DocumentAuthor = NULL;
2041  DocumentDate = NULL;
2042  DocumentStyle = LATEX_REPORT;
2043  MinorDocumentStyle = 0;
2044  BibliographyStyleString = copystring(_T("plain"));
2045  DocumentStyleString = copystring(_T("report"));
2046  MinorDocumentStyleString = NULL;
2047
2048  // gt - Changed this so if this is the final pass
2049  // then we DO want to remove these macros, so that
2050  // memory is not MASSIVELY leaked if the user
2051  // does not exit the program, but instead runs
2052  // the program again
2053  if ((passNumber == 1 && !runTwice) ||
2054      (passNumber == 2 && runTwice))
2055  {
2056/* Don't want to remove custom macros after each pass.*/
2057      SetFontSizes(10);
2058      wxNode *node = CustomMacroList.GetFirst();
2059      while (node)
2060      {
2061        CustomMacro *macro = (CustomMacro *)node->GetData();
2062        delete macro;
2063        delete node;
2064        node = CustomMacroList.GetFirst();
2065      }
2066  }
2067/**/
2068  TexReferences.BeginFind();
2069  wxHashTable::Node *refNode = TexReferences.Next();
2070  while (refNode)
2071  {
2072    TexRef *ref = (TexRef *)refNode->GetData();
2073    delete ref;
2074    refNode = TexReferences.Next();
2075  }
2076  TexReferences.Clear();
2077
2078  wxNode* bibNode = BibList.GetFirst();
2079  while (bibNode)
2080  {
2081    BibEntry *entry = (BibEntry *)bibNode->GetData();
2082    delete entry;
2083    delete bibNode;
2084    bibNode = BibList.GetFirst();
2085  }
2086  CitationList.Clear();
2087  ResetTopicCounter();
2088}
2089
2090// There is likely to be one set of macros used by all utilities.
2091void DefineDefaultMacros(void)
2092{
2093  // Put names which subsume other names at the TOP
2094  // so they get recognized first
2095
2096  AddMacroDef(ltACCENT_GRAVE,        _T("`"), 1);
2097  AddMacroDef(ltACCENT_ACUTE,        _T("'"), 1);
2098  AddMacroDef(ltACCENT_CARET,        _T("^"), 1);
2099  AddMacroDef(ltACCENT_UMLAUT,       _T("\""), 1);
2100  AddMacroDef(ltACCENT_TILDE,        _T("~"), 1);
2101  AddMacroDef(ltACCENT_DOT,          _T("."), 1);
2102  AddMacroDef(ltACCENT_CADILLA,      _T("c"), 1);
2103  AddMacroDef(ltSMALLSPACE1,         _T(","), 0);
2104  AddMacroDef(ltSMALLSPACE2,         _T(";"), 0);
2105
2106  AddMacroDef(ltABSTRACT,            _T("abstract"), 1);
2107  AddMacroDef(ltADDCONTENTSLINE,     _T("addcontentsline"), 3);
2108  AddMacroDef(ltADDTOCOUNTER,        _T("addtocounter"), 2);
2109  AddMacroDef(ltALEPH,               _T("aleph"), 0);
2110  AddMacroDef(ltALPHA,               _T("alpha"), 0);
2111  AddMacroDef(ltALPH1,               _T("alph"), 1);
2112  AddMacroDef(ltALPH2,               _T("Alph"), 1);
2113  AddMacroDef(ltANGLE,               _T("angle"), 0);
2114  AddMacroDef(ltAPPENDIX,            _T("appendix"), 0);
2115  AddMacroDef(ltAPPROX,              _T("approx"), 0);
2116  AddMacroDef(ltARABIC,              _T("arabic"), 1);
2117  AddMacroDef(ltARRAY,               _T("array"), 1);
2118  AddMacroDef(ltAST,                 _T("ast"), 0);
2119  AddMacroDef(ltASYMP,               _T("asymp"), 0);
2120  AddMacroDef(ltAUTHOR,              _T("author"), 1);
2121
2122  AddMacroDef(ltBACKGROUNDCOLOUR,    _T("backgroundcolour"), 1);
2123  AddMacroDef(ltBACKGROUNDIMAGE,     _T("backgroundimage"), 1);
2124  AddMacroDef(ltBACKGROUND,          _T("background"), 1);
2125  AddMacroDef(ltBACKSLASHRAW,        _T("backslashraw"), 0);
2126  AddMacroDef(ltBACKSLASH,           _T("backslash"), 0);
2127  AddMacroDef(ltBASELINESKIP,        _T("baselineskip"), 1);
2128  AddMacroDef(ltBCOL,                _T("bcol"), 2);
2129  AddMacroDef(ltBETA,                _T("beta"), 0);
2130  AddMacroDef(ltBFSERIES,            _T("bfseries"), 1);
2131  AddMacroDef(ltBF,                  _T("bf"), 1);
2132  AddMacroDef(ltBIBITEM,             _T("bibitem"), 2);
2133             // For convenience, bibitem has 2 args: label and item.
2134                              // The Latex syntax permits writing as 2 args.
2135  AddMacroDef(ltBIBLIOGRAPHYSTYLE,   _T("bibliographystyle"), 1);
2136  AddMacroDef(ltBIBLIOGRAPHY,        _T("bibliography"), 1);
2137  AddMacroDef(ltBIGTRIANGLEDOWN,     _T("bigtriangledown"), 0);
2138  AddMacroDef(ltBOT,                 _T("bot"), 0);
2139  AddMacroDef(ltBOXIT,               _T("boxit"), 1);
2140  AddMacroDef(ltBOX,                 _T("box"), 0);
2141  AddMacroDef(ltBRCLEAR,             _T("brclear"), 0);
2142  AddMacroDef(ltBULLET,              _T("bullet"), 0);
2143
2144  AddMacroDef(ltCAPTIONSTAR,         _T("caption*"), 1);
2145  AddMacroDef(ltCAPTION,             _T("caption"), 1);
2146  AddMacroDef(ltCAP,                 _T("cap"), 0);
2147  AddMacroDef(ltCDOTS,               _T("cdots"), 0);
2148  AddMacroDef(ltCDOT,                _T("cdot"), 0);
2149  AddMacroDef(ltCENTERLINE,          _T("centerline"), 1);
2150  AddMacroDef(ltCENTERING,           _T("centering"), 0);
2151  AddMacroDef(ltCENTER,              _T("center"), 1);
2152  AddMacroDef(ltCEXTRACT,            _T("cextract"), 0);
2153  AddMacroDef(ltCHAPTERHEADING,      _T("chapterheading"), 1);
2154  AddMacroDef(ltCHAPTERSTAR,         _T("chapter*"), 1);
2155  AddMacroDef(ltCHAPTER,             _T("chapter"), 1);
2156  AddMacroDef(ltCHI,                 _T("chi"), 0);
2157  AddMacroDef(ltCINSERT,             _T("cinsert"), 0);
2158  AddMacroDef(ltCIRC,                _T("circ"), 0);
2159  AddMacroDef(ltCITE,                _T("cite"), 1);
2160  AddMacroDef(ltCLASS,               _T("class"), 1);
2161  AddMacroDef(ltCLEARDOUBLEPAGE,     _T("cleardoublepage"), 0);
2162  AddMacroDef(ltCLEARPAGE,           _T("clearpage"), 0);
2163  AddMacroDef(ltCLINE,               _T("cline"), 1);
2164  AddMacroDef(ltCLIPSFUNC,           _T("clipsfunc"), 3);
2165  AddMacroDef(ltCLUBSUIT,            _T("clubsuit"), 0);
2166  AddMacroDef(ltCOLUMNSEP,           _T("columnsep"), 1);
2167  AddMacroDef(ltCOMMENT,             _T("comment"), 1, true);
2168  AddMacroDef(ltCONG,                _T("cong"), 0);
2169  AddMacroDef(ltCOPYRIGHT,           _T("copyright"), 0);
2170  AddMacroDef(ltCPARAM,              _T("cparam"), 2);
2171  AddMacroDef(ltCHEAD,               _T("chead"), 1);
2172  AddMacroDef(ltCFOOT,               _T("cfoot"), 1);
2173  AddMacroDef(ltCUP,                 _T("cup"), 0);
2174
2175  AddMacroDef(ltDASHV,               _T("dashv"), 0);
2176  AddMacroDef(ltDATE,                _T("date"), 1);
2177  AddMacroDef(ltDELTA,               _T("delta"), 0);
2178  AddMacroDef(ltCAP_DELTA,           _T("Delta"), 0);
2179  AddMacroDef(ltDEFINECOLOUR,        _T("definecolour"), 4);
2180  AddMacroDef(ltDEFINECOLOR,         _T("definecolor"), 4);
2181  AddMacroDef(ltDESCRIPTION,         _T("description"), 1);
2182  AddMacroDef(ltDESTRUCT,            _T("destruct"), 1);
2183  AddMacroDef(ltDIAMOND2,            _T("diamond2"), 0);
2184  AddMacroDef(ltDIAMOND,             _T("diamond"), 0);
2185  AddMacroDef(ltDIV,                 _T("div"), 0);
2186  AddMacroDef(ltDOCUMENTCLASS,       _T("documentclass"), 1);
2187  AddMacroDef(ltDOCUMENTSTYLE,       _T("documentstyle"), 1);
2188  AddMacroDef(ltDOCUMENT,            _T("document"), 1);
2189  AddMacroDef(ltDOUBLESPACE,         _T("doublespace"), 1);
2190  AddMacroDef(ltDOTEQ,               _T("doteq"), 0);
2191  AddMacroDef(ltDOWNARROW,           _T("downarrow"), 0);
2192  AddMacroDef(ltDOWNARROW2,          _T("Downarrow"), 0);
2193
2194  AddMacroDef(ltEMPTYSET,            _T("emptyset"), 0);
2195  AddMacroDef(ltEMPH,                _T("emph"), 1);
2196  AddMacroDef(ltEM,                  _T("em"), 1);
2197  AddMacroDef(ltENUMERATE,           _T("enumerate"), 1);
2198  AddMacroDef(ltEPSILON,             _T("epsilon"), 0);
2199  AddMacroDef(ltEQUATION,            _T("equation"), 1);
2200  AddMacroDef(ltEQUIV,               _T("equiv"), 0);
2201  AddMacroDef(ltETA,                 _T("eta"), 0);
2202  AddMacroDef(ltEVENSIDEMARGIN,      _T("evensidemargin"), 1);
2203  AddMacroDef(ltEXISTS,              _T("exists"), 0);
2204
2205  AddMacroDef(ltFBOX,                _T("fbox"), 1);
2206  AddMacroDef(ltFCOL,                _T("fcol"), 2);
2207  AddMacroDef(ltFIGURE,              _T("figure"), 1);
2208  AddMacroDef(ltFIGURESTAR,          _T("figure*"), 1);
2209  AddMacroDef(ltFLUSHLEFT,           _T("flushleft"), 1);
2210  AddMacroDef(ltFLUSHRIGHT,          _T("flushright"), 1);
2211  AddMacroDef(ltFOLLOWEDLINKCOLOUR,  _T("followedlinkcolour"), 1);
2212  AddMacroDef(ltFOOTHEIGHT,          _T("footheight"), 1);
2213  AddMacroDef(ltFOOTNOTEPOPUP,       _T("footnotepopup"), 2);
2214  AddMacroDef(ltFOOTNOTE,            _T("footnote"), 1);
2215  AddMacroDef(ltFOOTSKIP,            _T("footskip"), 1);
2216  AddMacroDef(ltFORALL,              _T("forall"), 0);
2217  AddMacroDef(ltFRAMEBOX,            _T("framebox"), 1);
2218  AddMacroDef(ltFROWN,               _T("frown"), 0);
2219  AddMacroDef(ltFUNCTIONSECTION,     _T("functionsection"), 1);
2220  AddMacroDef(ltFUNC,                _T("func"), 3);
2221  AddMacroDef(ltFOOTNOTESIZE,        _T("footnotesize"), 0);
2222  AddMacroDef(ltFANCYPLAIN,          _T("fancyplain"), 2);
2223
2224  AddMacroDef(ltGAMMA,               _T("gamma"), 0);
2225  AddMacroDef(ltCAP_GAMMA,           _T("Gamma"), 0);
2226  AddMacroDef(ltGEQ,                 _T("geq"), 0);
2227  AddMacroDef(ltGE,                  _T("ge"), 0);
2228  AddMacroDef(ltGG,                  _T("gg"), 0);
2229  AddMacroDef(ltGLOSSARY,            _T("glossary"), 1);
2230  AddMacroDef(ltGLOSS,               _T("gloss"), 1);
2231
2232  AddMacroDef(ltHEADHEIGHT,          _T("headheight"), 1);
2233  AddMacroDef(ltHEARTSUIT,           _T("heartsuit"), 0);
2234  AddMacroDef(ltHELPGLOSSARY,        _T("helpglossary"), 1);
2235  AddMacroDef(ltHELPIGNORE,          _T("helpignore"), 1, true);
2236  AddMacroDef(ltHELPONLY,            _T("helponly"), 1);
2237  AddMacroDef(ltHELPINPUT,           _T("helpinput"), 1);
2238  AddMacroDef(ltHELPFONTFAMILY,      _T("helpfontfamily"), 1);
2239  AddMacroDef(ltHELPFONTSIZE,        _T("helpfontsize"), 1);
2240  AddMacroDef(ltHELPREFN,            _T("helprefn"), 2);
2241  AddMacroDef(ltHELPREF,             _T("helpref"), 2);
2242  AddMacroDef(ltHFILL,               _T("hfill"), 0);
2243  AddMacroDef(ltHLINE,               _T("hline"), 0);
2244  AddMacroDef(ltHRULE,               _T("hrule"), 0);
2245  AddMacroDef(ltHSPACESTAR,          _T("hspace*"), 1);
2246  AddMacroDef(ltHSPACE,              _T("hspace"), 1);
2247  AddMacroDef(ltHSKIPSTAR,           _T("hskip*"), 1);
2248  AddMacroDef(ltHSKIP,               _T("hskip"), 1);
2249  AddMacroDef(lthuge,                _T("huge"), 1);
2250  AddMacroDef(ltHuge,                _T("Huge"), 1);
2251  AddMacroDef(ltHUGE,                _T("HUGE"), 1);
2252  AddMacroDef(ltHTMLIGNORE,          _T("htmlignore"), 1);
2253  AddMacroDef(ltHTMLONLY,            _T("htmlonly"), 1);
2254
2255  AddMacroDef(ltIM,                  _T("im"), 0);
2256  AddMacroDef(ltINCLUDEONLY,         _T("includeonly"), 1);
2257  AddMacroDef(ltINCLUDE,             _T("include"), 1);
2258  AddMacroDef(ltINDENTED,            _T("indented"), 2);
2259  AddMacroDef(ltINDEX,               _T("index"), 1);
2260  AddMacroDef(ltINPUT,               _T("input"), 1, true);
2261  AddMacroDef(ltIOTA,                _T("iota"), 0);
2262  AddMacroDef(ltITEMIZE,             _T("itemize"), 1);
2263  AddMacroDef(ltITEM,                _T("item"), 0);
2264  AddMacroDef(ltIMAGEMAP,            _T("imagemap"), 3);
2265  AddMacroDef(ltIMAGEL,              _T("imagel"), 2);
2266  AddMacroDef(ltIMAGER,              _T("imager"), 2);
2267  AddMacroDef(ltIMAGE,               _T("image"), 2);
2268  AddMacroDef(ltIN,                  _T("in"), 0);
2269  AddMacroDef(ltINFTY,               _T("infty"), 0);
2270  AddMacroDef(ltITSHAPE,             _T("itshape"), 1);
2271  AddMacroDef(ltIT,                  _T("it"), 1);
2272  AddMacroDef(ltITEMSEP,             _T("itemsep"), 1);
2273  AddMacroDef(ltINSERTATLEVEL,       _T("insertatlevel"), 2);
2274
2275  AddMacroDef(ltKAPPA,               _T("kappa"), 0);
2276  AddMacroDef(ltKILL,                _T("kill"), 0);
2277
2278  AddMacroDef(ltLABEL,               _T("label"), 1);
2279  AddMacroDef(ltLAMBDA,              _T("lambda"), 0);
2280  AddMacroDef(ltCAP_LAMBDA,          _T("Lambda"), 0);
2281  AddMacroDef(ltlarge,               _T("large"), 1);
2282  AddMacroDef(ltLarge,               _T("Large"), 1);
2283  AddMacroDef(ltLARGE,               _T("LARGE"), 1);
2284  AddMacroDef(ltLATEXIGNORE,         _T("latexignore"), 1);
2285  AddMacroDef(ltLATEXONLY,           _T("latexonly"), 1);
2286  AddMacroDef(ltLATEX,               _T("LaTeX"), 0);
2287  AddMacroDef(ltLBOX,                _T("lbox"), 1);
2288  AddMacroDef(ltLBRACERAW,           _T("lbraceraw"), 0);
2289  AddMacroDef(ltLDOTS,               _T("ldots"), 0);
2290  AddMacroDef(ltLEQ,                 _T("leq"), 0);
2291  AddMacroDef(ltLE,                  _T("le"), 0);
2292  AddMacroDef(ltLEFTARROW,           _T("leftarrow"), 0);
2293  AddMacroDef(ltLEFTRIGHTARROW,      _T("leftrightarrow"), 0);
2294  AddMacroDef(ltLEFTARROW2,          _T("Leftarrow"), 0);
2295  AddMacroDef(ltLEFTRIGHTARROW2,     _T("Leftrightarrow"), 0);
2296  AddMacroDef(ltLINEBREAK,           _T("linebreak"), 0);
2297  AddMacroDef(ltLINKCOLOUR,          _T("linkcolour"), 1);
2298  AddMacroDef(ltLISTOFFIGURES,       _T("listoffigures"), 0);
2299  AddMacroDef(ltLISTOFTABLES,        _T("listoftables"), 0);
2300  AddMacroDef(ltLHEAD,               _T("lhead"), 1);
2301  AddMacroDef(ltLFOOT,               _T("lfoot"), 1);
2302  AddMacroDef(ltLOWERCASE,           _T("lowercase"), 1);
2303  AddMacroDef(ltLL,                  _T("ll"), 0);
2304
2305  AddMacroDef(ltMAKEGLOSSARY,        _T("makeglossary"), 0);
2306  AddMacroDef(ltMAKEINDEX,           _T("makeindex"), 0);
2307  AddMacroDef(ltMAKETITLE,           _T("maketitle"), 0);
2308  AddMacroDef(ltMARKRIGHT,           _T("markright"), 1);
2309  AddMacroDef(ltMARKBOTH,            _T("markboth"), 2);
2310  AddMacroDef(ltMARGINPARWIDTH,      _T("marginparwidth"), 1);
2311  AddMacroDef(ltMARGINPARSEP,        _T("marginparsep"), 1);
2312  AddMacroDef(ltMARGINPARODD,        _T("marginparodd"), 1);
2313  AddMacroDef(ltMARGINPAREVEN,       _T("marginpareven"), 1);
2314  AddMacroDef(ltMARGINPAR,           _T("marginpar"), 1);
2315  AddMacroDef(ltMBOX,                _T("mbox"), 1);
2316  AddMacroDef(ltMDSERIES,            _T("mdseries"), 1);
2317  AddMacroDef(ltMEMBERSECTION,       _T("membersection"), 1);
2318  AddMacroDef(ltMEMBER,              _T("member"), 2);
2319  AddMacroDef(ltMID,                 _T("mid"), 0);
2320  AddMacroDef(ltMODELS,              _T("models"), 0);
2321  AddMacroDef(ltMP,                  _T("mp"), 0);
2322  AddMacroDef(ltMULTICOLUMN,         _T("multicolumn"), 3);
2323  AddMacroDef(ltMU,                  _T("mu"), 0);
2324
2325  AddMacroDef(ltNABLA,               _T("nabla"), 0);
2326  AddMacroDef(ltNEG,                 _T("neg"), 0);
2327  AddMacroDef(ltNEQ,                 _T("neq"), 0);
2328  AddMacroDef(ltNEWCOUNTER,          _T("newcounter"), 1, false, (bool)FORBID_ABSOLUTELY);
2329  AddMacroDef(ltNEWLINE,             _T("newline"), 0);
2330  AddMacroDef(ltNEWPAGE,             _T("newpage"), 0);
2331  AddMacroDef(ltNI,                  _T("ni"), 0);
2332  AddMacroDef(ltNOCITE,              _T("nocite"), 1);
2333  AddMacroDef(ltNOINDENT,            _T("noindent"), 0);
2334  AddMacroDef(ltNOLINEBREAK,         _T("nolinebreak"), 0);
2335  AddMacroDef(ltNOPAGEBREAK,         _T("nopagebreak"), 0);
2336  AddMacroDef(ltNORMALSIZE,          _T("normalsize"), 1);
2337  AddMacroDef(ltNORMALBOX,           _T("normalbox"), 1);
2338  AddMacroDef(ltNORMALBOXD,          _T("normalboxd"), 1);
2339  AddMacroDef(ltNOTEQ,               _T("noteq"), 0);
2340  AddMacroDef(ltNOTIN,               _T("notin"), 0);
2341  AddMacroDef(ltNOTSUBSET,           _T("notsubset"), 0);
2342  AddMacroDef(ltNU,                  _T("nu"), 0);
2343
2344  AddMacroDef(ltODDSIDEMARGIN,       _T("oddsidemargin"), 1);
2345  AddMacroDef(ltOMEGA,               _T("omega"), 0);
2346  AddMacroDef(ltCAP_OMEGA,           _T("Omega"), 0);
2347  AddMacroDef(ltONECOLUMN,           _T("onecolumn"), 0);
2348  AddMacroDef(ltOPLUS,               _T("oplus"), 0);
2349  AddMacroDef(ltOSLASH,              _T("oslash"), 0);
2350  AddMacroDef(ltOTIMES,              _T("otimes"), 0);
2351
2352  AddMacroDef(ltPAGEBREAK,           _T("pagebreak"), 0);
2353  AddMacroDef(ltPAGEREF,             _T("pageref"), 1);
2354  AddMacroDef(ltPAGESTYLE,           _T("pagestyle"), 1);
2355  AddMacroDef(ltPAGENUMBERING,       _T("pagenumbering"), 1);
2356  AddMacroDef(ltPARAGRAPHSTAR,       _T("paragraph*"), 1);
2357  AddMacroDef(ltPARAGRAPH,           _T("paragraph"), 1);
2358  AddMacroDef(ltPARALLEL,            _T("parallel"), 0);
2359  AddMacroDef(ltPARAM,               _T("param"), 2);
2360  AddMacroDef(ltPARINDENT,           _T("parindent"), 1);
2361  AddMacroDef(ltPARSKIP,             _T("parskip"), 1);
2362  AddMacroDef(ltPARTIAL,             _T("partial"), 0);
2363  AddMacroDef(ltPARTSTAR,            _T("part*"), 1);
2364  AddMacroDef(ltPART,                _T("part"), 1);
2365  AddMacroDef(ltPAR,                 _T("par"), 0);
2366  AddMacroDef(ltPERP,                _T("perp"), 0);
2367  AddMacroDef(ltPHI,                 _T("phi"), 0);
2368  AddMacroDef(ltCAP_PHI,             _T("Phi"), 0);
2369  AddMacroDef(ltPFUNC,               _T("pfunc"), 3);
2370  AddMacroDef(ltPICTURE,             _T("picture"), 1);
2371  AddMacroDef(ltPI,                  _T("pi"), 0);
2372  AddMacroDef(ltCAP_PI,              _T("Pi"), 0);
2373  AddMacroDef(ltPM,                  _T("pm"), 0);
2374  AddMacroDef(ltPOPREFONLY,          _T("poprefonly"), 1);
2375  AddMacroDef(ltPOPREF,              _T("popref"), 2);
2376  AddMacroDef(ltPOUNDS,              _T("pounds"), 0);
2377  AddMacroDef(ltPREC,                _T("prec"), 0);
2378  AddMacroDef(ltPRECEQ,              _T("preceq"), 0);
2379  AddMacroDef(ltPRINTINDEX,          _T("printindex"), 0);
2380  AddMacroDef(ltPROPTO,              _T("propto"), 0);
2381  AddMacroDef(ltPSBOXTO,             _T("psboxto"), 1, false, (bool)FORBID_ABSOLUTELY);
2382  AddMacroDef(ltPSBOX,               _T("psbox"), 1, false, (bool)FORBID_ABSOLUTELY);
2383  AddMacroDef(ltPSI,                 _T("psi"), 0);
2384  AddMacroDef(ltCAP_PSI,             _T("Psi"), 0);
2385
2386  AddMacroDef(ltQUOTE,               _T("quote"), 1);
2387  AddMacroDef(ltQUOTATION,           _T("quotation"), 1);
2388
2389  AddMacroDef(ltRAGGEDBOTTOM,        _T("raggedbottom"), 0);
2390  AddMacroDef(ltRAGGEDLEFT,          _T("raggedleft"), 0);
2391  AddMacroDef(ltRAGGEDRIGHT,         _T("raggedright"), 0);
2392  AddMacroDef(ltRBRACERAW,           _T("rbraceraw"), 0);
2393  AddMacroDef(ltREF,                 _T("ref"), 1);
2394  AddMacroDef(ltREGISTERED,          _T("registered"), 0);
2395  AddMacroDef(ltRE,                  _T("we"), 0);
2396  AddMacroDef(ltRHO,                 _T("rho"), 0);
2397  AddMacroDef(ltRIGHTARROW,          _T("rightarrow"), 0);
2398  AddMacroDef(ltRIGHTARROW2,         _T("rightarrow2"), 0);
2399  AddMacroDef(ltRMFAMILY,            _T("rmfamily"), 1);
2400  AddMacroDef(ltRM,                  _T("rm"), 1);
2401  AddMacroDef(ltROMAN,               _T("roman"), 1);
2402  AddMacroDef(ltROMAN2,              _T("Roman"), 1);
2403//  AddMacroDef(lt"row", 1);
2404  AddMacroDef(ltRTFSP,               _T("rtfsp"), 0);
2405  AddMacroDef(ltRTFIGNORE,           _T("rtfignore"), 1);
2406  AddMacroDef(ltRTFONLY,             _T("rtfonly"), 1);
2407  AddMacroDef(ltRULEDROW,            _T("ruledrow"), 1);
2408  AddMacroDef(ltDRULED,              _T("druled"), 1);
2409  AddMacroDef(ltRULE,                _T("rule"), 2);
2410  AddMacroDef(ltRHEAD,               _T("rhead"), 1);
2411  AddMacroDef(ltRFOOT,               _T("rfoot"), 1);
2412  AddMacroDef(ltROW,                 _T("row"), 1);
2413
2414  AddMacroDef(ltSCSHAPE,             _T("scshape"), 1);
2415  AddMacroDef(ltSC,                  _T("sc"), 1);
2416  AddMacroDef(ltSECTIONHEADING,      _T("sectionheading"), 1);
2417  AddMacroDef(ltSECTIONSTAR,         _T("section*"), 1);
2418  AddMacroDef(ltSECTION,             _T("section"), 1);
2419  AddMacroDef(ltSETCOUNTER,          _T("setcounter"), 2);
2420  AddMacroDef(ltSFFAMILY,            _T("sffamily"), 1);
2421  AddMacroDef(ltSF,                  _T("sf"), 1);
2422  AddMacroDef(ltSHARP,               _T("sharp"), 0);
2423  AddMacroDef(ltSHORTCITE,           _T("shortcite"), 1);
2424  AddMacroDef(ltSIGMA,               _T("sigma"), 0);
2425  AddMacroDef(ltCAP_SIGMA,           _T("Sigma"), 0);
2426  AddMacroDef(ltSIM,                 _T("sim"), 0);
2427  AddMacroDef(ltSIMEQ,               _T("simeq"), 0);
2428  AddMacroDef(ltSINGLESPACE,         _T("singlespace"), 1);
2429  AddMacroDef(ltSIZEDBOX,            _T("sizedbox"), 2);
2430  AddMacroDef(ltSIZEDBOXD,           _T("sizedboxd"), 2);
2431  AddMacroDef(ltSLOPPYPAR,           _T("sloppypar"), 1);
2432  AddMacroDef(ltSLOPPY,              _T("sloppy"), 0);
2433  AddMacroDef(ltSLSHAPE,             _T("slshape"), 1);
2434  AddMacroDef(ltSL,                  _T("sl"), 1);
2435  AddMacroDef(ltSMALL,               _T("small"), 1);
2436  AddMacroDef(ltSMILE,               _T("smile"), 0);
2437  AddMacroDef(ltSS,                  _T("ss"), 0);
2438  AddMacroDef(ltSTAR,                _T("star"), 0);
2439  AddMacroDef(ltSUBITEM,             _T("subitem"), 0);
2440  AddMacroDef(ltSUBPARAGRAPHSTAR,    _T("subparagraph*"), 1);
2441  AddMacroDef(ltSUBPARAGRAPH,        _T("subparagraph"), 1);
2442  AddMacroDef(ltSPECIAL,             _T("special"), 1);
2443  AddMacroDef(ltSUBSECTIONSTAR,      _T("subsection*"), 1);
2444  AddMacroDef(ltSUBSECTION,          _T("subsection"), 1);
2445  AddMacroDef(ltSUBSETEQ,            _T("subseteq"), 0);
2446  AddMacroDef(ltSUBSET,              _T("subset"), 0);
2447  AddMacroDef(ltSUCC,                _T("succ"), 0);
2448  AddMacroDef(ltSUCCEQ,              _T("succeq"), 0);
2449  AddMacroDef(ltSUPSETEQ,            _T("supseteq"), 0);
2450  AddMacroDef(ltSUPSET,              _T("supset"), 0);
2451  AddMacroDef(ltSUBSUBSECTIONSTAR,   _T("subsubsection*"), 1);
2452  AddMacroDef(ltSUBSUBSECTION,       _T("subsubsection"), 1);
2453  AddMacroDef(ltSUPERTABULAR,        _T("supertabular"), 2, false);
2454  AddMacroDef(ltSURD,                _T("surd"), 0);
2455  AddMacroDef(ltSCRIPTSIZE,          _T("scriptsize"), 1);
2456  AddMacroDef(ltSETHEADER,           _T("setheader"), 6);
2457  AddMacroDef(ltSETFOOTER,           _T("setfooter"), 6);
2458  AddMacroDef(ltSETHOTSPOTCOLOUR,    _T("sethotspotcolour"), 1);
2459  AddMacroDef(ltSETHOTSPOTCOLOR,     _T("sethotspotcolor"), 1);
2460  AddMacroDef(ltSETHOTSPOTUNDERLINE, _T("sethotspotunderline"), 1);
2461  AddMacroDef(ltSETTRANSPARENCY,     _T("settransparency"), 1);
2462  AddMacroDef(ltSPADESUIT,           _T("spadesuit"), 0);
2463
2464  AddMacroDef(ltTABBING,             _T("tabbing"), 2);
2465  AddMacroDef(ltTABLEOFCONTENTS,     _T("tableofcontents"), 0);
2466  AddMacroDef(ltTABLE,               _T("table"), 1);
2467  AddMacroDef(ltTABULAR,             _T("tabular"), 2, false);
2468  AddMacroDef(ltTAB,                 _T("tab"), 0);
2469  AddMacroDef(ltTAU,                 _T("tau"), 0);
2470  AddMacroDef(ltTEXTRM,              _T("textrm"), 1);
2471  AddMacroDef(ltTEXTSF,              _T("textsf"), 1);
2472  AddMacroDef(ltTEXTTT,              _T("texttt"), 1);
2473  AddMacroDef(ltTEXTBF,              _T("textbf"), 1);
2474  AddMacroDef(ltTEXTIT,              _T("textit"), 1);
2475  AddMacroDef(ltTEXTSL,              _T("textsl"), 1);
2476  AddMacroDef(ltTEXTSC,              _T("textsc"), 1);
2477  AddMacroDef(ltTEXTWIDTH,           _T("textwidth"), 1);
2478  AddMacroDef(ltTEXTHEIGHT,          _T("textheight"), 1);
2479  AddMacroDef(ltTEXTCOLOUR,          _T("textcolour"), 1);
2480  AddMacroDef(ltTEX,                 _T("TeX"), 0);
2481  AddMacroDef(ltTHEBIBLIOGRAPHY,     _T("thebibliography"), 2);
2482  AddMacroDef(ltTHETA,               _T("theta"), 0);
2483  AddMacroDef(ltTIMES,               _T("times"), 0);
2484  AddMacroDef(ltCAP_THETA,           _T("Theta"), 0);
2485  AddMacroDef(ltTITLEPAGE,           _T("titlepage"), 1);
2486  AddMacroDef(ltTITLE,               _T("title"), 1);
2487  AddMacroDef(ltTINY,                _T("tiny"), 1);
2488  AddMacroDef(ltTODAY,               _T("today"), 0);
2489  AddMacroDef(ltTOPMARGIN,           _T("topmargin"), 1);
2490  AddMacroDef(ltTOPSKIP,             _T("topskip"), 1);
2491  AddMacroDef(ltTRIANGLE,            _T("triangle"), 0);
2492  AddMacroDef(ltTTFAMILY,            _T("ttfamily"), 1);
2493  AddMacroDef(ltTT,                  _T("tt"), 1);
2494  AddMacroDef(ltTYPEIN,              _T("typein"), 1);
2495  AddMacroDef(ltTYPEOUT,             _T("typeout"), 1);
2496  AddMacroDef(ltTWOCOLWIDTHA,        _T("twocolwidtha"), 1);
2497  AddMacroDef(ltTWOCOLWIDTHB,        _T("twocolwidthb"), 1);
2498  AddMacroDef(ltTWOCOLSPACING,       _T("twocolspacing"), 1);
2499  AddMacroDef(ltTWOCOLITEMRULED,     _T("twocolitemruled"), 2);
2500  AddMacroDef(ltTWOCOLITEM,          _T("twocolitem"), 2);
2501  AddMacroDef(ltTWOCOLLIST,          _T("twocollist"), 1);
2502  AddMacroDef(ltTWOCOLUMN,           _T("twocolumn"), 0);
2503  AddMacroDef(ltTHEPAGE,             _T("thepage"), 0);
2504  AddMacroDef(ltTHECHAPTER,          _T("thechapter"), 0);
2505  AddMacroDef(ltTHESECTION,          _T("thesection"), 0);
2506  AddMacroDef(ltTHISPAGESTYLE,       _T("thispagestyle"), 1);
2507
2508  AddMacroDef(ltUNDERLINE,           _T("underline"), 1);
2509  AddMacroDef(ltUPSILON,             _T("upsilon"), 0);
2510  AddMacroDef(ltCAP_UPSILON,         _T("Upsilon"), 0);
2511  AddMacroDef(ltUPARROW,             _T("uparrow"), 0);
2512  AddMacroDef(ltUPARROW2,            _T("Uparrow"), 0);
2513  AddMacroDef(ltUPPERCASE,           _T("uppercase"), 1);
2514  AddMacroDef(ltUPSHAPE,             _T("upshape"), 1);
2515  AddMacroDef(ltURLREF,              _T("urlref"), 2);
2516  AddMacroDef(ltUSEPACKAGE,          _T("usepackage"), 1);
2517
2518  AddMacroDef(ltVAREPSILON,          _T("varepsilon"), 0);
2519  AddMacroDef(ltVARPHI,              _T("varphi"), 0);
2520  AddMacroDef(ltVARPI,               _T("varpi"), 0);
2521  AddMacroDef(ltVARRHO,              _T("varrho"), 0);
2522  AddMacroDef(ltVARSIGMA,            _T("varsigma"), 0);
2523  AddMacroDef(ltVARTHETA,            _T("vartheta"), 0);
2524  AddMacroDef(ltVDOTS,               _T("vdots"), 0);
2525  AddMacroDef(ltVEE,                 _T("vee"), 0);
2526  AddMacroDef(ltVERBATIMINPUT,       _T("verbatiminput"), 1);
2527  AddMacroDef(ltVERBATIM,            _T("verbatim"), 1);
2528  AddMacroDef(ltVERBSTAR,            _T("verb*"), 1);
2529  AddMacroDef(ltVERB,                _T("verb"), 1);
2530  AddMacroDef(ltVERSE,               _T("verse"), 1);
2531  AddMacroDef(ltVFILL,               _T("vfill"), 0);
2532  AddMacroDef(ltVLINE,               _T("vline"), 0);
2533  AddMacroDef(ltVOID,                _T("void"), 0);
2534  AddMacroDef(ltVDASH,               _T("vdash"), 0);
2535  AddMacroDef(ltVRULE,               _T("vrule"), 0);
2536  AddMacroDef(ltVSPACESTAR,          _T("vspace*"), 1);
2537  AddMacroDef(ltVSKIPSTAR,           _T("vskip*"), 1);
2538  AddMacroDef(ltVSPACE,              _T("vspace"), 1);
2539  AddMacroDef(ltVSKIP,               _T("vskip"), 1);
2540
2541  AddMacroDef(ltWEDGE,               _T("wedge"), 0);
2542  AddMacroDef(ltWXCLIPS,             _T("wxclips"), 0);
2543  AddMacroDef(ltWINHELPIGNORE,       _T("winhelpignore"), 1);
2544  AddMacroDef(ltWINHELPONLY,         _T("winhelponly"), 1);
2545  AddMacroDef(ltWP,                  _T("wp"), 0);
2546
2547  AddMacroDef(ltXI,                  _T("xi"), 0);
2548  AddMacroDef(ltCAP_XI,              _T("Xi"), 0);
2549  AddMacroDef(ltXLPIGNORE,           _T("xlpignore"), 1);
2550  AddMacroDef(ltXLPONLY,             _T("xlponly"), 1);
2551
2552  AddMacroDef(ltZETA,                _T("zeta"), 0);
2553
2554  AddMacroDef(ltSPACE,               _T(" "), 0);
2555  AddMacroDef(ltBACKSLASHCHAR,       _T("\\"), 0);
2556  AddMacroDef(ltPIPE,                _T("|"), 0);
2557  AddMacroDef(ltFORWARDSLASH,        _T("/"), 0);
2558  AddMacroDef(ltUNDERSCORE,          _T("_"), 0);
2559  AddMacroDef(ltAMPERSAND,           _T("&"), 0);
2560  AddMacroDef(ltPERCENT,             _T("%"), 0);
2561  AddMacroDef(ltDOLLAR,              _T("$"), 0);
2562  AddMacroDef(ltHASH,                _T("#"), 0);
2563  AddMacroDef(ltLPARENTH,            _T("("), 0);
2564  AddMacroDef(ltRPARENTH,            _T(")"), 0);
2565  AddMacroDef(ltLBRACE,              _T("{"), 0);
2566  AddMacroDef(ltRBRACE,              _T("}"), 0);
2567//  AddMacroDef(ltEQUALS,              _T("="), 0);
2568  AddMacroDef(ltRANGLEBRA,           _T(">"), 0);
2569  AddMacroDef(ltLANGLEBRA,           _T("<"), 0);
2570  AddMacroDef(ltPLUS,                _T("+"), 0);
2571  AddMacroDef(ltDASH,                _T("-"), 0);
2572  AddMacroDef(ltAT_SYMBOL,           _T("@"), 0);
2573//  AddMacroDef(ltSINGLEQUOTE,         _T("'"), 0);
2574//  AddMacroDef(ltBACKQUOTE,           _T("`"), 0);
2575}
2576
2577/*
2578 * Default behaviour, should be called by client if can't match locally.
2579 *
2580 */
2581
2582// Called on start/end of macro examination
2583void DefaultOnMacro(int macroId, int no_args, bool start)
2584{
2585  switch (macroId)
2586  {
2587    // Default behaviour for abstract
2588    case ltABSTRACT:
2589    {
2590      if (start)
2591      {
2592        // Write the heading
2593        FakeCurrentSection(AbstractNameString);
2594        OnMacro(ltPAR, 0, true);
2595        OnMacro(ltPAR, 0, false);
2596      }
2597      else
2598      {
2599        if (DocumentStyle == LATEX_ARTICLE)
2600          sectionNo --;
2601        else
2602          chapterNo --;
2603      }
2604      break;
2605    }
2606
2607    // Default behaviour for glossary
2608    case ltHELPGLOSSARY:
2609    {
2610      if (start)
2611      {
2612        // Write the heading
2613        FakeCurrentSection(GlossaryNameString);
2614        OnMacro(ltPAR, 0, true);
2615        OnMacro(ltPAR, 0, false);
2616        if ((convertMode == TEX_RTF) && !winHelp)
2617        {
2618          OnMacro(ltPAR, 0, true);
2619          OnMacro(ltPAR, 0, false);
2620        }
2621      }
2622      break;
2623    }
2624    case ltSPECIALAMPERSAND:
2625      if (start)
2626        TexOutput(_T("  "));
2627      break;
2628
2629    case ltCINSERT:
2630      if (start)
2631      {
2632        if (convertMode == TEX_HTML)
2633            TexOutput(_T("&lt;&lt;"));
2634        else
2635            TexOutput(_T("<<"), true);
2636      }
2637      break;
2638    case ltCEXTRACT:
2639      if (start)
2640      {
2641        if (convertMode == TEX_HTML)
2642            TexOutput(_T("&gt;&gt;"));
2643        else
2644            TexOutput(_T(">>"), true);
2645      }
2646      break;
2647    case ltDESTRUCT:
2648      if (start)
2649        TexOutput(_T("~"), true);
2650      break;
2651    case ltTILDE:
2652      if (start)
2653        TexOutput(_T("~"), true);
2654      break;
2655    case ltSPECIALTILDE:
2656      if (start)
2657        TexOutput(_T(" "), true);
2658      break;
2659    case ltUNDERSCORE:
2660      if (start)
2661        TexOutput(_T("_"), true);
2662      break;
2663    case ltHASH:
2664      if (start)
2665        TexOutput(_T("#"), true);
2666      break;
2667    case ltAMPERSAND:
2668      if (start)
2669        TexOutput(_T("&"), true);
2670      break;
2671    case ltSPACE:
2672      if (start)
2673        TexOutput(_T(" "), true);
2674      break;
2675    case ltPIPE:
2676      if (start)
2677        TexOutput(_T("|"), true);
2678      break;
2679    case ltPERCENT:
2680      if (start)
2681        TexOutput(_T("%"), true);
2682      break;
2683    case ltDOLLAR:
2684      if (start)
2685        TexOutput(_T("$"), true);
2686      break;
2687    case ltLPARENTH:
2688      if (start)
2689        TexOutput(_T(""), true);
2690      break;
2691    case ltRPARENTH:
2692      if (start)
2693        TexOutput(_T(""), true);
2694      break;
2695    case ltLBRACE:
2696      if (start)
2697        TexOutput(_T("{"), true);
2698      break;
2699    case ltRBRACE:
2700      if (start)
2701        TexOutput(_T("}"), true);
2702      break;
2703    case ltCOPYRIGHT:
2704      if (start)
2705        TexOutput(_T("(c)"), true);
2706      break;
2707    case ltREGISTERED:
2708      if (start)
2709        TexOutput(_T("(r)"), true);
2710      break;
2711    case ltBACKSLASH:
2712      if (start)
2713        TexOutput(_T("\\"), true);
2714      break;
2715    case ltLDOTS:
2716    case ltCDOTS:
2717      if (start)
2718        TexOutput(_T("..."), true);
2719      break;
2720    case ltVDOTS:
2721      if (start)
2722        TexOutput(_T("|"), true);
2723      break;
2724    case ltLATEX:
2725      if (start)
2726        TexOutput(_T("LaTeX"), true);
2727      break;
2728    case ltTEX:
2729      if (start)
2730        TexOutput(_T("TeX"), true);
2731      break;
2732    case ltPOUNDS:
2733      if (start)
2734        // FIXME: this is valid only if the output is iso-8859-1
2735        TexOutput(wxString::FromAscii("�"), true);
2736      break;
2737    case ltSPECIALDOUBLEDOLLAR:  // Interpret as center
2738      OnMacro(ltCENTER, no_args, start);
2739      break;
2740    case ltEMPH:
2741    case ltTEXTSL:
2742    case ltSLSHAPE:
2743    case ltSL:
2744      OnMacro(ltIT, no_args, start);
2745      break;
2746    case ltPARAGRAPH:
2747    case ltPARAGRAPHSTAR:
2748    case ltSUBPARAGRAPH:
2749    case ltSUBPARAGRAPHSTAR:
2750      OnMacro(ltSUBSUBSECTION, no_args, start);
2751      break;
2752    case ltTODAY:
2753    {
2754      if (start)
2755      {
2756        time_t when;
2757        (void) time(&when);
2758        TexOutput(wxCtime(&when), true);
2759      }
2760      break;
2761    }
2762    case ltNOINDENT:
2763      if (start)
2764        ParIndent = 0;
2765      break;
2766
2767    // Symbols
2768    case ltALPHA:
2769      if (start) TexOutput(_T("alpha"));
2770      break;
2771    case ltBETA:
2772      if (start) TexOutput(_T("beta"));
2773      break;
2774    case ltGAMMA:
2775      if (start) TexOutput(_T("gamma"));
2776      break;
2777    case ltDELTA:
2778      if (start) TexOutput(_T("delta"));
2779      break;
2780    case ltEPSILON:
2781    case ltVAREPSILON:
2782      if (start) TexOutput(_T("epsilon"));
2783      break;
2784    case ltZETA:
2785      if (start) TexOutput(_T("zeta"));
2786      break;
2787    case ltETA:
2788      if (start) TexOutput(_T("eta"));
2789      break;
2790    case ltTHETA:
2791    case ltVARTHETA:
2792      if (start) TexOutput(_T("theta"));
2793      break;
2794    case ltIOTA:
2795      if (start) TexOutput(_T("iota"));
2796      break;
2797    case ltKAPPA:
2798      if (start) TexOutput(_T("kappa"));
2799      break;
2800    case ltLAMBDA:
2801      if (start) TexOutput(_T("lambda"));
2802      break;
2803    case ltMU:
2804      if (start) TexOutput(_T("mu"));
2805      break;
2806    case ltNU:
2807      if (start) TexOutput(_T("nu"));
2808      break;
2809    case ltXI:
2810      if (start) TexOutput(_T("xi"));
2811      break;
2812    case ltPI:
2813    case ltVARPI:
2814      if (start) TexOutput(_T("pi"));
2815      break;
2816    case ltRHO:
2817    case ltVARRHO:
2818      if (start) TexOutput(_T("rho"));
2819      break;
2820    case ltSIGMA:
2821    case ltVARSIGMA:
2822      if (start) TexOutput(_T("sigma"));
2823      break;
2824    case ltTAU:
2825      if (start) TexOutput(_T("tau"));
2826      break;
2827    case ltUPSILON:
2828      if (start) TexOutput(_T("upsilon"));
2829      break;
2830    case ltPHI:
2831    case ltVARPHI:
2832      if (start) TexOutput(_T("phi"));
2833      break;
2834    case ltCHI:
2835      if (start) TexOutput(_T("chi"));
2836      break;
2837    case ltPSI:
2838      if (start) TexOutput(_T("psi"));
2839      break;
2840    case ltOMEGA:
2841      if (start) TexOutput(_T("omega"));
2842      break;
2843    case ltCAP_GAMMA:
2844      if (start) TexOutput(_T("GAMMA"));
2845      break;
2846    case ltCAP_DELTA:
2847      if (start) TexOutput(_T("DELTA"));
2848      break;
2849    case ltCAP_THETA:
2850      if (start) TexOutput(_T("THETA"));
2851      break;
2852    case ltCAP_LAMBDA:
2853      if (start) TexOutput(_T("LAMBDA"));
2854      break;
2855    case ltCAP_XI:
2856      if (start) TexOutput(_T("XI"));
2857      break;
2858    case ltCAP_PI:
2859      if (start) TexOutput(_T("PI"));
2860      break;
2861    case ltCAP_SIGMA:
2862      if (start) TexOutput(_T("SIGMA"));
2863      break;
2864    case ltCAP_UPSILON:
2865      if (start) TexOutput(_T("UPSILON"));
2866      break;
2867    case ltCAP_PHI:
2868      if (start) TexOutput(_T("PHI"));
2869      break;
2870    case ltCAP_PSI:
2871      if (start) TexOutput(_T("PSI"));
2872      break;
2873    case ltCAP_OMEGA:
2874      if (start) TexOutput(_T("OMEGA"));
2875      break;
2876
2877    // Binary operation symbols
2878    case ltLE:
2879    case ltLEQ:
2880      if (start)
2881      {
2882        if (convertMode == TEX_HTML)
2883            TexOutput(_T("&lt;="));
2884        else
2885            TexOutput(_T("<="));
2886      }
2887      break;
2888    case ltLL:
2889      if (start)
2890      {
2891        if (convertMode == TEX_HTML)
2892            TexOutput(_T("&lt;&lt;"));
2893        else
2894            TexOutput(_T("<<"));
2895      }
2896      break;
2897    case ltSUBSET:
2898      if (start) TexOutput(_T("SUBSET"));
2899      break;
2900    case ltSUBSETEQ:
2901      if (start) TexOutput(_T("SUBSETEQ"));
2902      break;
2903    case ltIN:
2904      if (start) TexOutput(_T("IN"));
2905      break;
2906    case ltVDASH:
2907      if (start) TexOutput(_T("VDASH"));
2908      break;
2909    case ltMODELS:
2910      if (start) TexOutput(_T("MODELS"));
2911      break;
2912    case ltGE:
2913    case ltGEQ:
2914    {
2915      if (start)
2916      {
2917        if (convertMode == TEX_HTML)
2918            TexOutput(_T("&gt;="));
2919        else
2920            TexOutput(_T(">="));
2921      }
2922      break;
2923    }
2924    case ltGG:
2925      if (start)
2926      {
2927        if (convertMode == TEX_HTML)
2928            TexOutput(_T("&gt;&gt;"));
2929        else
2930            TexOutput(_T(">>"));
2931      }
2932      break;
2933    case ltSUPSET:
2934      if (start) TexOutput(_T("SUPSET"));
2935      break;
2936    case ltSUPSETEQ:
2937      if (start) TexOutput(_T("SUPSETEQ"));
2938      break;
2939    case ltNI:
2940      if (start) TexOutput(_T("NI"));
2941      break;
2942    case ltDASHV:
2943      if (start) TexOutput(_T("DASHV"));
2944      break;
2945    case ltPERP:
2946      if (start) TexOutput(_T("PERP"));
2947      break;
2948    case ltNEQ:
2949      if (start) TexOutput(_T("NEQ"));
2950      break;
2951    case ltDOTEQ:
2952      if (start) TexOutput(_T("DOTEQ"));
2953      break;
2954    case ltAPPROX:
2955      if (start) TexOutput(_T("APPROX"));
2956      break;
2957    case ltCONG:
2958      if (start) TexOutput(_T("CONG"));
2959      break;
2960    case ltEQUIV:
2961      if (start) TexOutput(_T("EQUIV"));
2962      break;
2963    case ltPROPTO:
2964      if (start) TexOutput(_T("PROPTO"));
2965      break;
2966    case ltPREC:
2967      if (start) TexOutput(_T("PREC"));
2968      break;
2969    case ltPRECEQ:
2970      if (start) TexOutput(_T("PRECEQ"));
2971      break;
2972    case ltPARALLEL:
2973      if (start) TexOutput(_T("|"));
2974      break;
2975    case ltSIM:
2976      if (start) TexOutput(_T("~"));
2977      break;
2978    case ltSIMEQ:
2979      if (start) TexOutput(_T("SIMEQ"));
2980      break;
2981    case ltASYMP:
2982      if (start) TexOutput(_T("ASYMP"));
2983      break;
2984    case ltSMILE:
2985      if (start) TexOutput(_T(":-)"));
2986      break;
2987    case ltFROWN:
2988      if (start) TexOutput(_T(":-("));
2989      break;
2990    case ltSUCC:
2991      if (start) TexOutput(_T("SUCC"));
2992      break;
2993    case ltSUCCEQ:
2994      if (start) TexOutput(_T("SUCCEQ"));
2995      break;
2996    case ltMID:
2997      if (start) TexOutput(_T("|"));
2998      break;
2999
3000    // Negated relation symbols
3001    case ltNOTEQ:
3002      if (start) TexOutput(_T("!="));
3003      break;
3004    case ltNOTIN:
3005      if (start) TexOutput(_T("NOTIN"));
3006      break;
3007    case ltNOTSUBSET:
3008      if (start) TexOutput(_T("NOTSUBSET"));
3009      break;
3010
3011    // Arrows
3012    case ltLEFTARROW:
3013      if (start)
3014      {
3015        if (convertMode == TEX_HTML)
3016            TexOutput(_T("&lt;--"));
3017        else
3018            TexOutput(_T("<--"));
3019      }
3020      break;
3021    case ltLEFTARROW2:
3022      if (start)
3023      {
3024        if (convertMode == TEX_HTML)
3025            TexOutput(_T("&lt;=="));
3026        else
3027            TexOutput(_T("<=="));
3028      }
3029      break;
3030    case ltRIGHTARROW:
3031      if (start)
3032      {
3033        if (convertMode == TEX_HTML)
3034            TexOutput(_T("--&gt;"));
3035        else
3036            TexOutput(_T("-->"));
3037      }
3038      break;
3039    case ltRIGHTARROW2:
3040      if (start)
3041      {
3042        if (convertMode == TEX_HTML)
3043            TexOutput(_T("==&gt;"));
3044        else
3045            TexOutput(_T("==>"));
3046      }
3047      break;
3048    case ltLEFTRIGHTARROW:
3049      if (start)
3050      {
3051        if (convertMode == TEX_HTML)
3052            TexOutput(_T("&lt;--&gt;"));
3053        else
3054            TexOutput(_T("<-->"));
3055      }
3056      break;
3057    case ltLEFTRIGHTARROW2:
3058      if (start)
3059      {
3060        if (convertMode == TEX_HTML)
3061            TexOutput(_T("&lt;==&gt;"));
3062        else
3063            TexOutput(_T("<==>"));
3064      }
3065      break;
3066    case ltUPARROW:
3067      if (start) TexOutput(_T("UPARROW"));
3068      break;
3069    case ltUPARROW2:
3070      if (start) TexOutput(_T("UPARROW2"));
3071      break;
3072    case ltDOWNARROW:
3073      if (start) TexOutput(_T("DOWNARROW"));
3074      break;
3075    case ltDOWNARROW2:
3076      if (start) TexOutput(_T("DOWNARROW2"));
3077      break;
3078    // Miscellaneous symbols
3079    case ltALEPH:
3080      if (start) TexOutput(_T("ALEPH"));
3081      break;
3082    case ltWP:
3083      if (start) TexOutput(_T("WP"));
3084      break;
3085    case ltRE:
3086      if (start) TexOutput(_T("RE"));
3087      break;
3088    case ltIM:
3089      if (start) TexOutput(_T("IM"));
3090      break;
3091    case ltEMPTYSET:
3092      if (start) TexOutput(_T("EMPTYSET"));
3093      break;
3094    case ltNABLA:
3095      if (start) TexOutput(_T("NABLA"));
3096      break;
3097    case ltSURD:
3098      if (start) TexOutput(_T("SURD"));
3099      break;
3100    case ltPARTIAL:
3101      if (start) TexOutput(_T("PARTIAL"));
3102      break;
3103    case ltBOT:
3104      if (start) TexOutput(_T("BOT"));
3105      break;
3106    case ltFORALL:
3107      if (start) TexOutput(_T("FORALL"));
3108      break;
3109    case ltEXISTS:
3110      if (start) TexOutput(_T("EXISTS"));
3111      break;
3112    case ltNEG:
3113      if (start) TexOutput(_T("NEG"));
3114      break;
3115    case ltSHARP:
3116      if (start) TexOutput(_T("SHARP"));
3117      break;
3118    case ltANGLE:
3119      if (start) TexOutput(_T("ANGLE"));
3120      break;
3121    case ltTRIANGLE:
3122      if (start) TexOutput(_T("TRIANGLE"));
3123      break;
3124    case ltCLUBSUIT:
3125      if (start) TexOutput(_T("CLUBSUIT"));
3126      break;
3127    case ltDIAMONDSUIT:
3128      if (start) TexOutput(_T("DIAMONDSUIT"));
3129      break;
3130    case ltHEARTSUIT:
3131      if (start) TexOutput(_T("HEARTSUIT"));
3132      break;
3133    case ltSPADESUIT:
3134      if (start) TexOutput(_T("SPADESUIT"));
3135      break;
3136    case ltINFTY:
3137      if (start) TexOutput(_T("INFTY"));
3138      break;
3139    case ltPM:
3140      if (start) TexOutput(_T("PM"));
3141      break;
3142    case ltMP:
3143      if (start) TexOutput(_T("MP"));
3144      break;
3145    case ltTIMES:
3146      if (start) TexOutput(_T("TIMES"));
3147      break;
3148    case ltDIV:
3149      if (start) TexOutput(_T("DIV"));
3150      break;
3151    case ltCDOT:
3152      if (start) TexOutput(_T("CDOT"));
3153      break;
3154    case ltAST:
3155      if (start) TexOutput(_T("AST"));
3156      break;
3157    case ltSTAR:
3158      if (start) TexOutput(_T("STAR"));
3159      break;
3160    case ltCAP:
3161      if (start) TexOutput(_T("CAP"));
3162      break;
3163    case ltCUP:
3164      if (start) TexOutput(_T("CUP"));
3165      break;
3166    case ltVEE:
3167      if (start) TexOutput(_T("VEE"));
3168      break;
3169    case ltWEDGE:
3170      if (start) TexOutput(_T("WEDGE"));
3171      break;
3172    case ltCIRC:
3173      if (start) TexOutput(_T("CIRC"));
3174      break;
3175    case ltBULLET:
3176      if (start) TexOutput(_T("BULLET"));
3177      break;
3178    case ltDIAMOND:
3179      if (start) TexOutput(_T("DIAMOND"));
3180      break;
3181    case ltOSLASH:
3182      if (start) TexOutput(_T("OSLASH"));
3183      break;
3184    case ltBOX:
3185      if (start) TexOutput(_T("BOX"));
3186      break;
3187    case ltDIAMOND2:
3188      if (start) TexOutput(_T("DIAMOND2"));
3189      break;
3190    case ltBIGTRIANGLEDOWN:
3191      if (start) TexOutput(_T("BIGTRIANGLEDOWN"));
3192      break;
3193    case ltOPLUS:
3194      if (start) TexOutput(_T("OPLUS"));
3195      break;
3196    case ltOTIMES:
3197      if (start) TexOutput(_T("OTIMES"));
3198      break;
3199    case ltSS:
3200      if (start) TexOutput(_T("s"));
3201      break;
3202    case ltBACKSLASHRAW:
3203      if (start) TexOutput(_T("\\"));
3204      break;
3205    case ltLBRACERAW:
3206      if (start) TexOutput(_T("{"));
3207      break;
3208    case ltRBRACERAW:
3209      if (start) TexOutput(_T("}"));
3210      break;
3211    case ltSMALLSPACE1:
3212    case ltSMALLSPACE2:
3213      if (start) TexOutput(_T(" "));
3214      break;
3215    default:
3216      break;
3217  }
3218}
3219
3220// Called on start/end of argument examination
3221bool DefaultOnArgument(int macroId, int arg_no, bool start)
3222{
3223  switch (macroId)
3224  {
3225    case ltREF:
3226    {
3227    if (arg_no == 1 && start)
3228    {
3229      wxChar *refName = GetArgData();
3230      if (refName)
3231      {
3232        TexRef *texRef = FindReference(refName);
3233        if (texRef)
3234        {
3235          // Must strip the 'section' or 'chapter' or 'figure' text
3236          // from a normal 'ref' reference
3237          wxChar buf[150];
3238          wxStrcpy(buf, texRef->sectionNumber);
3239          int len = wxStrlen(buf);
3240          int i = 0;
3241          if (wxStrcmp(buf, _T("??")) != 0)
3242          {
3243            while (i < len)
3244            {
3245              if (buf[i] == ' ')
3246              {
3247                i ++;
3248                break;
3249              }
3250              else i ++;
3251            }
3252          }
3253          TexOutput(texRef->sectionNumber + i, true);
3254        }
3255        else
3256        {
3257           wxString informBuf;
3258           informBuf.Printf(_T("Warning: unresolved reference '%s'"), refName);
3259           OnInform((wxChar *)informBuf.c_str());
3260        }
3261      }
3262      else TexOutput(_T("??"), true);
3263      return false;
3264    }
3265    break;
3266    }
3267    case ltLABEL:
3268    {
3269      return false;
3270    }
3271    case ltAUTHOR:
3272    {
3273      if (start && (arg_no == 1))
3274        DocumentAuthor = GetArgChunk();
3275      return false;
3276    }
3277    case ltDATE:
3278    {
3279      if (start && (arg_no == 1))
3280        DocumentDate = GetArgChunk();
3281      return false;
3282    }
3283    case ltTITLE:
3284    {
3285      if (start && (arg_no == 1))
3286        DocumentTitle = GetArgChunk();
3287      return false;
3288    }
3289  case ltDOCUMENTCLASS:
3290  case ltDOCUMENTSTYLE:
3291  {
3292    if (start && !IsArgOptional())
3293    {
3294      DocumentStyleString = copystring(GetArgData());
3295      if (wxStrncmp(DocumentStyleString, _T("art"), 3) == 0)
3296        DocumentStyle = LATEX_ARTICLE;
3297      else if (wxStrncmp(DocumentStyleString, _T("rep"), 3) == 0)
3298        DocumentStyle = LATEX_REPORT;
3299      else if (wxStrncmp(DocumentStyleString, _T("book"), 4) == 0 ||
3300               wxStrncmp(DocumentStyleString, _T("thesis"), 6) == 0)
3301        DocumentStyle = LATEX_BOOK;
3302      else if (wxStrncmp(DocumentStyleString, _T("letter"), 6) == 0)
3303        DocumentStyle = LATEX_LETTER;
3304      else if (wxStrncmp(DocumentStyleString, _T("slides"), 6) == 0)
3305        DocumentStyle = LATEX_SLIDES;
3306
3307      if (StringMatch(_T("10"), DocumentStyleString))
3308        SetFontSizes(10);
3309      else if (StringMatch(_T("11"), DocumentStyleString))
3310        SetFontSizes(11);
3311      else if (StringMatch(_T("12"), DocumentStyleString))
3312        SetFontSizes(12);
3313
3314      OnMacro(ltHELPFONTSIZE, 1, true);
3315      wxSnprintf(currentArgData, 2000, _T("%d"), normalFont);
3316      haveArgData = true;
3317      OnArgument(ltHELPFONTSIZE, 1, true);
3318      OnArgument(ltHELPFONTSIZE, 1, false);
3319      haveArgData = false;
3320      OnMacro(ltHELPFONTSIZE, 1, false);
3321    }
3322    else if (start && IsArgOptional())
3323    {
3324      MinorDocumentStyleString = copystring(GetArgData());
3325
3326      if (StringMatch(_T("10"), MinorDocumentStyleString))
3327        SetFontSizes(10);
3328      else if (StringMatch(_T("11"), MinorDocumentStyleString))
3329        SetFontSizes(11);
3330      else if (StringMatch(_T("12"), MinorDocumentStyleString))
3331        SetFontSizes(12);
3332    }
3333    return false;
3334  }
3335  case ltBIBLIOGRAPHYSTYLE:
3336  {
3337    if (start && !IsArgOptional())
3338      BibliographyStyleString = copystring(GetArgData());
3339    return false;
3340  }
3341  case ltPAGESTYLE:
3342  {
3343    if (start && !IsArgOptional())
3344    {
3345      if (PageStyle) delete[] PageStyle;
3346      PageStyle = copystring(GetArgData());
3347    }
3348    return false;
3349  }
3350/*
3351  case ltLHEAD:
3352  {
3353    if (start && !IsArgOptional())
3354      LeftHeader = GetArgChunk();
3355    return false;
3356    break;
3357  }
3358  case ltLFOOT:
3359  {
3360    if (start && !IsArgOptional())
3361      LeftFooter = GetArgChunk();
3362    return false;
3363    break;
3364  }
3365  case ltCHEAD:
3366  {
3367    if (start && !IsArgOptional())
3368      CentreHeader = GetArgChunk();
3369    return false;
3370    break;
3371  }
3372  case ltCFOOT:
3373  {
3374    if (start && !IsArgOptional())
3375      CentreFooter = GetArgChunk();
3376    return false;
3377    break;
3378  }
3379  case ltRHEAD:
3380  {
3381    if (start && !IsArgOptional())
3382      RightHeader = GetArgChunk();
3383    return false;
3384    break;
3385  }
3386  case ltRFOOT:
3387  {
3388    if (start && !IsArgOptional())
3389      RightFooter = GetArgChunk();
3390    return false;
3391    break;
3392  }
3393*/
3394  case ltCITE:
3395  case ltSHORTCITE:
3396  {
3397    if (start && !IsArgOptional())
3398    {
3399      wxChar *citeKeys = GetArgData();
3400      int pos = 0;
3401      wxChar *citeKey = ParseMultifieldString(citeKeys, &pos);
3402      while (citeKey)
3403      {
3404        AddCitation(citeKey);
3405        TexRef *ref = FindReference(citeKey);
3406        if (ref)
3407        {
3408          TexOutput(ref->sectionNumber, true);
3409          if (wxStrcmp(ref->sectionNumber, _T("??")) == 0)
3410          {
3411            wxString informBuf;
3412            informBuf.Printf(_T("Warning: unresolved citation %s."), citeKey);
3413            OnInform((wxChar *)informBuf.c_str());
3414          }
3415        }
3416        citeKey = ParseMultifieldString(citeKeys, &pos);
3417        if (citeKey)
3418        {
3419          TexOutput(_T(", "), true);
3420        }
3421      }
3422      return false;
3423    }
3424    break;
3425  }
3426  case ltNOCITE:
3427  {
3428    if (start && !IsArgOptional())
3429    {
3430      wxChar *citeKey = GetArgData();
3431      AddCitation(citeKey);
3432      return false;
3433    }
3434    break;
3435  }
3436  case ltHELPFONTSIZE:
3437  {
3438    if (start)
3439    {
3440      wxChar *data = GetArgData();
3441      if (wxStrcmp(data, _T("10")) == 0)
3442        SetFontSizes(10);
3443      else if (wxStrcmp(data, _T("11")) == 0)
3444        SetFontSizes(11);
3445      else if (wxStrcmp(data, _T("12")) == 0)
3446        SetFontSizes(12);
3447      return false;
3448    }
3449    break;
3450  }
3451  case ltPAGEREF:
3452  {
3453    if (start)
3454    {
3455      TexOutput(_T(" ??"), true);
3456      return false;
3457    }
3458    break;
3459  }
3460  case ltPARSKIP:
3461  {
3462    if (start && arg_no == 1)
3463    {
3464      wxChar *data = GetArgData();
3465      ParSkip = ParseUnitArgument(data);
3466      return false;
3467    }
3468    break;
3469  }
3470  case ltPARINDENT:
3471  {
3472    if (start && arg_no == 1)
3473    {
3474      wxChar *data = GetArgData();
3475      ParIndent = ParseUnitArgument(data);
3476      return false;
3477    }
3478    break;
3479  }
3480  case ltSL:
3481  {
3482    return OnArgument(ltIT, arg_no, start);
3483  }
3484  case ltSPECIALDOUBLEDOLLAR:
3485  {
3486    return OnArgument(ltCENTER, arg_no, start);
3487  }
3488  case ltPARAGRAPH:
3489  case ltPARAGRAPHSTAR:
3490  case ltSUBPARAGRAPH:
3491  case ltSUBPARAGRAPHSTAR:
3492  {
3493    return OnArgument(ltSUBSUBSECTION, arg_no, start);
3494  }
3495  case ltTYPEOUT:
3496  {
3497    if (start)
3498      OnInform(GetArgData());
3499    break;
3500  }
3501  case ltFOOTNOTE:
3502  {
3503    if (start)
3504      TexOutput(_T(" ("), true);
3505    else
3506      TexOutput(_T(")"), true);
3507    break;
3508  }
3509  case ltBIBLIOGRAPHY:
3510  {
3511    if (start)
3512    {
3513      int ch;
3514      wxChar smallBuf[2];
3515      smallBuf[1] = 0;
3516      FILE *fd = wxFopen(TexBibName, _T("r"));
3517      if (fd)
3518      {
3519        ch = getc(fd);
3520        smallBuf[0] = (wxChar)ch;
3521        while (ch != EOF)
3522        {
3523          TexOutput(smallBuf);
3524          ch = getc(fd);
3525          smallBuf[0] = (wxChar)ch;
3526        }
3527        fclose(fd);
3528      }
3529      else
3530      {
3531        OnInform(_T("Run Tex2RTF again to include bibliography."));
3532      }
3533
3534      // Read in the .bib file, resolve all known references, write out the RTF.
3535      wxChar *allFiles = GetArgData();
3536      int pos = 0;
3537      wxChar *bibFile = ParseMultifieldString(allFiles, &pos);
3538      while (bibFile)
3539      {
3540        wxChar fileBuf[300];
3541        wxStrcpy(fileBuf, bibFile);
3542        wxString actualFile = TexPathList.FindValidPath(fileBuf);
3543        if (actualFile.empty())
3544        {
3545          wxStrcat(fileBuf, _T(".bib"));
3546          actualFile = TexPathList.FindValidPath(fileBuf);
3547        }
3548        if (!actualFile.empty())
3549        {
3550          if (!ReadBib((wxChar*) (const wxChar*) actualFile))
3551          {
3552            wxString errBuf;
3553            errBuf.Printf(_T(".bib file %s not found or malformed"), (const wxChar*) actualFile);
3554            OnError((wxChar *)errBuf.c_str());
3555          }
3556        }
3557        else
3558        {
3559          wxString errBuf;
3560          errBuf.Printf(_T(".bib file %s not found"), fileBuf);
3561          OnError((wxChar *)errBuf.c_str());
3562        }
3563        bibFile = ParseMultifieldString(allFiles, &pos);
3564      }
3565
3566      ResolveBibReferences();
3567
3568      // Write it a new bib section in the appropriate format.
3569      FILE *save1 = CurrentOutput1;
3570      FILE *save2 = CurrentOutput2;
3571      FILE *Biblio = wxFopen(TexTmpBibName, _T("w"));
3572      SetCurrentOutput(Biblio);
3573      OutputBib();
3574      fclose(Biblio);
3575      if (wxFileExists(TexTmpBibName))
3576      {
3577        if (wxFileExists(TexBibName)) wxRemoveFile(TexBibName);
3578        wxRenameFile(TexTmpBibName, TexBibName);
3579      }
3580      SetCurrentOutputs(save1, save2);
3581      return false;
3582    }
3583    break;
3584  }
3585  case ltMULTICOLUMN:
3586    return (start && (arg_no == 3));
3587  case ltSCSHAPE:
3588  case ltTEXTSC:
3589  case ltSC:
3590  {
3591    if (start && (arg_no == 1))
3592    {
3593      wxChar *s = GetArgData();
3594      if (s)
3595      {
3596        wxChar *s1 = copystring(s);
3597        int i;
3598        for (i = 0; i < (int)wxStrlen(s); i++)
3599          s1[i] = (wxChar)wxToupper(s[i]);
3600        TexOutput(s1);
3601        delete[] s1;
3602        return false;
3603      }
3604      else return true;
3605
3606    }
3607    return true;
3608  }
3609  case ltLOWERCASE:
3610  {
3611    if (start && (arg_no == 1))
3612    {
3613      wxChar *s = GetArgData();
3614      if (s)
3615      {
3616        wxChar *s1 = copystring(s);
3617        int i;
3618        for (i = 0; i < (int)wxStrlen(s); i++)
3619          s1[i] = (wxChar)wxTolower(s[i]);
3620        TexOutput(s1);
3621        delete[] s1;
3622        return false;
3623      }
3624      else return true;
3625
3626    }
3627    return true;
3628  }
3629  case ltUPPERCASE:
3630  {
3631    if (start && (arg_no == 1))
3632    {
3633      wxChar *s = GetArgData();
3634      if (s)
3635      {
3636        wxChar *s1 = copystring(s);
3637        int i;
3638        for (i = 0; i < (int)wxStrlen(s); i++)
3639          s1[i] = (wxChar)wxToupper(s[i]);
3640        TexOutput(s1);
3641        delete[] s1;
3642        return false;
3643      }
3644      else return true;
3645
3646    }
3647    return true;
3648  }
3649  case ltPOPREF:  // Ignore second argument by default
3650    return (start && (arg_no == 1));
3651  case ltTWOCOLUMN:
3652    return true;
3653  case ltXLPIGNORE:
3654    return ((convertMode == TEX_XLP) ? false : true);
3655  case ltXLPONLY:
3656    return ((convertMode != TEX_XLP) ? false : true);
3657  case ltHTMLIGNORE:
3658    return ((convertMode == TEX_HTML) ? false : true);
3659  case ltHTMLONLY:
3660    return ((convertMode != TEX_HTML) ? false : true);
3661  case ltRTFIGNORE:
3662    return (((convertMode == TEX_RTF) && !winHelp) ? false : true);
3663  case ltRTFONLY:
3664    return (!((convertMode == TEX_RTF) && !winHelp) ? false : true);
3665  case ltWINHELPIGNORE:
3666    return (winHelp ? false : true);
3667  case ltWINHELPONLY:
3668    return (!winHelp ? false : true);
3669  case ltLATEXIGNORE:
3670    return true;
3671  case ltLATEXONLY:
3672    return false;
3673  case ltCLINE:
3674  case ltARABIC:
3675  case ltALPH1:
3676  case ltALPH2:
3677  case ltROMAN:
3678  case ltROMAN2:
3679  case ltSETCOUNTER:
3680  case ltADDTOCOUNTER:
3681  case ltADDCONTENTSLINE:
3682  case ltNEWCOUNTER:
3683  case ltTEXTWIDTH:
3684  case ltTEXTHEIGHT:
3685  case ltBASELINESKIP:
3686  case ltVSPACESTAR:
3687  case ltHSPACESTAR:
3688  case ltVSPACE:
3689  case ltHSPACE:
3690  case ltVSKIPSTAR:
3691  case ltHSKIPSTAR:
3692  case ltVSKIP:
3693  case ltHSKIP:
3694  case ltPAGENUMBERING:
3695  case ltTHEPAGE:
3696  case ltTHECHAPTER:
3697  case ltTHESECTION:
3698  case ltITEMSEP:
3699  case ltFANCYPLAIN:
3700  case ltCHEAD:
3701  case ltRHEAD:
3702  case ltLHEAD:
3703  case ltCFOOT:
3704  case ltRFOOT:
3705  case ltLFOOT:
3706  case ltTHISPAGESTYLE:
3707  case ltMARKRIGHT:
3708  case ltMARKBOTH:
3709  case ltEVENSIDEMARGIN:
3710  case ltODDSIDEMARGIN:
3711  case ltMARGINPAR:
3712  case ltMARGINPARWIDTH:
3713  case ltMARGINPARSEP:
3714  case ltMARGINPAREVEN:
3715  case ltMARGINPARODD:
3716  case ltTWOCOLWIDTHA:
3717  case ltTWOCOLWIDTHB:
3718  case ltTWOCOLSPACING:
3719  case ltSETHEADER:
3720  case ltSETFOOTER:
3721  case ltINDEX:
3722  case ltITEM:
3723  case ltBCOL:
3724  case ltFCOL:
3725  case ltSETHOTSPOTCOLOUR:
3726  case ltSETHOTSPOTCOLOR:
3727  case ltSETHOTSPOTUNDERLINE:
3728  case ltSETTRANSPARENCY:
3729  case ltUSEPACKAGE:
3730  case ltBACKGROUND:
3731  case ltBACKGROUNDCOLOUR:
3732  case ltBACKGROUNDIMAGE:
3733  case ltLINKCOLOUR:
3734  case ltFOLLOWEDLINKCOLOUR:
3735  case ltTEXTCOLOUR:
3736  case ltIMAGE:
3737  case ltIMAGEMAP:
3738  case ltIMAGEL:
3739  case ltIMAGER:
3740  case ltPOPREFONLY:
3741  case ltINSERTATLEVEL:
3742    return false;
3743  case ltTABULAR:
3744  case ltSUPERTABULAR:
3745  case ltINDENTED:
3746  case ltSIZEDBOX:
3747  case ltSIZEDBOXD:
3748    return (arg_no == 2);
3749  case ltDEFINECOLOUR:
3750  case ltDEFINECOLOR:
3751  {
3752    static int redVal = 0;
3753    static int greenVal = 0;
3754    static int blueVal = 0;
3755    static wxChar *colourName = NULL;
3756    if (start)
3757    {
3758      switch (arg_no)
3759      {
3760        case 1:
3761        {
3762          if (colourName) delete[] colourName;
3763          colourName = copystring(GetArgData());
3764          break;
3765        }
3766        case 2:
3767        {
3768          redVal = wxAtoi(GetArgData());
3769          break;
3770        }
3771        case 3:
3772        {
3773          greenVal = wxAtoi(GetArgData());
3774          break;
3775        }
3776        case 4:
3777        {
3778          blueVal = wxAtoi(GetArgData());
3779          AddColour(colourName, redVal, greenVal, blueVal);
3780          break;
3781        }
3782        default:
3783          break;
3784      }
3785    }
3786    return false;
3787  }
3788  case ltFIGURE:
3789  case ltFIGURESTAR:
3790  case ltNORMALBOX:
3791  case ltNORMALBOXD:
3792  default:
3793    return (!IsArgOptional());
3794  }
3795  return true;
3796}
3797