home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / utils / tex2rtf / src / rtfutils.cpp < prev    next >
C/C++ Source or Header  |  2002-07-19  |  136KB  |  5,300 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        rtfutils.cpp
  3. // Purpose:     Converts Latex to Word RTF/WinHelp RTF
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     7.9.93
  7. // RCS-ID:      $Id: rtfutils.cpp,v 1.11 2002/07/14 13:19:56 GD Exp $
  8. // Copyright:   (c) Julian Smart
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #ifndef WX_PRECOMP
  24. #include "wx/wx.h"
  25. #endif
  26.  
  27. #include "tex2any.h"
  28. #include "tex2rtf.h"
  29. #include <ctype.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32.  
  33. #ifdef __WIN32__
  34. #include <windows.h>
  35. #endif
  36.  
  37. #include "bmputils.h"
  38. #include "table.h"
  39.  
  40. wxList itemizeStack;
  41. static int indentLevel = 0;
  42. static int forbidParindent = 0; // if > 0, no parindent (e.g. in center environment)
  43. int forbidResetPar = 0; // If > 0, don't reset memory of having output a new par
  44.  
  45. static char *contentsLineSection = NULL;
  46. static char *contentsLineValue = NULL;
  47. static TexChunk *descriptionItemArg = NULL;
  48. static wxStringList environmentStack; // Stack of paragraph styles we need to remember
  49. static int footnoteCount = 0;
  50. static int citeCount = 1;
  51. extern char *FileRoot;
  52. extern bool winHelp;
  53. extern bool startedSections;
  54. extern FILE *Contents;
  55. extern FILE *Chapters;
  56. extern FILE *Popups;
  57. extern FILE *WinHelpContentsFile;
  58. extern char *RTFCharset;
  59. // This is defined in the Tex2Any library and isn't in use after parsing
  60. extern char *BigBuffer;
  61.  
  62. extern wxHashTable TexReferences;
  63.  
  64. // Are we in verbatim mode? If so, format differently.
  65. static bool inVerbatim = FALSE;
  66.  
  67. // We're in a series of PopRef topics, so don't output section headings
  68. bool inPopRefSection = FALSE;
  69.  
  70. // Green colour?
  71. static bool hotSpotColour = TRUE;
  72. static bool hotSpotUnderline = TRUE;
  73.  
  74. // Transparency (WHITE = transparent)
  75. static bool bitmapTransparency = TRUE;
  76.  
  77. // Linear RTF requires us to set the style per section.
  78. static char *currentNumberStyle = NULL;
  79. static int currentItemSep = 8;
  80. static int CurrentTextWidth = 8640; // Say, six inches
  81. static int CurrentLeftMarginOdd = 400;
  82. static int CurrentLeftMarginEven = 1440;
  83. static int CurrentRightMarginOdd = 1440;
  84. static int CurrentRightMarginEven = 400;
  85. static int CurrentMarginParWidth = 2000;
  86. static int CurrentMarginParSep = 400;  // Gap between marginpar and text
  87. static int CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  88. static int GutterWidth = 2300;
  89.  
  90. // Two-column table dimensions, in twips
  91. static int TwoColWidthA = 1500;
  92. static int TwoColWidthB = 3000;
  93.  
  94. const int PageWidth = 12242; // 8.25 inches wide for A4
  95.  
  96. // Remember the anchor in a helpref
  97. static TexChunk *helpRefText = NULL;
  98.  
  99. /*
  100.  * Flag to say we've just issued a \par\pard command, so don't
  101.  * repeat this unnecessarily.
  102.  *
  103.  */
  104.  
  105. int issuedNewParagraph = 0;
  106.  
  107. // Need to know whether we're in a table or figure for benefit
  108. // of listoffigures/listoftables
  109. static bool inFigure = FALSE;
  110. static bool inTable = FALSE;
  111.  
  112. /*
  113.  * Current topics
  114.  *
  115.  */
  116. static char *CurrentChapterName = NULL;
  117. static char *CurrentSectionName = NULL;
  118. static char *CurrentSubsectionName = NULL;
  119. static char *CurrentTopic = NULL;
  120.  
  121. static bool InPopups()
  122. {
  123.   if (CurrentChapterName && (strcmp(CurrentChapterName, "popups") == 0))
  124.     return TRUE;
  125.   if (CurrentSectionName && (strcmp(CurrentSectionName, "popups") == 0))
  126.     return TRUE;
  127.   return FALSE;
  128. }
  129.  
  130. static void SetCurrentTopic(char *s)
  131. {
  132.   if (CurrentTopic) delete[] CurrentTopic;
  133.   CurrentTopic = copystring(s);
  134. }
  135.  
  136. void SetCurrentChapterName(char *s)
  137. {
  138.   if (CurrentChapterName) delete[] CurrentChapterName;
  139.   CurrentChapterName = copystring(s);
  140.   SetCurrentTopic(s);
  141. }
  142. void SetCurrentSectionName(char *s)
  143. {
  144.   if (CurrentSectionName) delete[] CurrentSectionName;
  145.   CurrentSectionName = copystring(s);
  146.   SetCurrentTopic(s);
  147. }
  148. void SetCurrentSubsectionName(char *s)
  149. {
  150.   if (CurrentSubsectionName) delete[] CurrentSubsectionName;
  151.   CurrentSubsectionName = copystring(s);
  152.   SetCurrentTopic(s);
  153. }
  154.  
  155. // Indicate that a parent topic at level 'level' has children.
  156. // Level 1 is a chapter, 2 is a section, etc.
  157. void NotifyParentHasChildren(int parentLevel)
  158. {
  159.   char *parentTopic = NULL;
  160.   switch (parentLevel)
  161.   {
  162.     case 1:
  163.     {
  164.       parentTopic = CurrentChapterName;
  165.       break;
  166.     }
  167.     case 2:
  168.     {
  169.       parentTopic = CurrentSectionName;
  170.       break;
  171.     }
  172.     case 3:
  173.     {
  174.       parentTopic = CurrentSubsectionName;
  175.       break;
  176.     }
  177.     default:
  178.     {
  179.       break;
  180.     }
  181.   }
  182.   if (parentTopic)
  183.   {
  184.     TexTopic *texTopic = (TexTopic *)TopicTable.Get(parentTopic);
  185.     if (!texTopic)
  186.     {
  187.       texTopic = new TexTopic;
  188.       TopicTable.Put(parentTopic, texTopic);
  189.     }
  190.     texTopic->hasChildren = TRUE;
  191.   }
  192. }
  193.  
  194. // Have to keep a count of what levels are books, what are pages,
  195. // in order to correct for a Win95 bug which means that if you
  196. // have a book at level n, and then a page at level n, the page
  197. // ends up on level n + 1.
  198.  
  199. bool ContentsLevels[5];
  200.  
  201. // Reset below this level (starts from 1)
  202. void ResetContentsLevels(int l)
  203. {
  204.   int i;
  205.   for (i = l; i < 5; i++)
  206.     ContentsLevels[i] = FALSE;
  207.     
  208.   // There are always books on the top level
  209.   ContentsLevels[0] = TRUE;
  210. }
  211.  
  212. // Output a WinHelp section as a keyword, substituting
  213. // : for space.
  214. void OutputSectionKeyword(FILE *fd)
  215. {
  216.   OutputCurrentSectionToString(wxTex2RTFBuffer);
  217.   
  218.   unsigned int i;
  219.   for (i = 0; i < strlen(wxTex2RTFBuffer); i++)
  220.     if (wxTex2RTFBuffer[i] == ':')
  221.       wxTex2RTFBuffer[i] = ' ';
  222.     // Don't write to index if there's some RTF in the string
  223.     else if ( wxTex2RTFBuffer[i] == '{' )
  224.         return;
  225.  
  226.   fprintf(fd, "K{\\footnote {K} ");
  227.   fprintf(fd, "%s", wxTex2RTFBuffer);
  228.   
  229.   fprintf(fd, "}\n");
  230. }
  231.  
  232. // Write a line for the .cnt file, if we're doing this.
  233. void WriteWinHelpContentsFileLine(char *topicName, char *xitle, int level)
  234. {
  235.   // First, convert any RTF characters to ASCII
  236.   char title[255];
  237.   int s=0;
  238.   int d=0;
  239.   while ( (xitle[s]!=0)&&(d<255) )
  240.   {
  241.       char ch=xitle[s]&0xff;
  242.       if (ch==0x5c) {
  243.           char ch1=xitle[s+1]&0xff;
  244.           char ch2=xitle[s+2]&0xff;
  245.           char ch3=xitle[s+3]&0xff;
  246.           char ch4=xitle[s+4]&0xff;
  247.           s+=4; // next character          
  248.           char a=0;
  249.           if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x36)) { title[d++]='÷';  a=1; }
  250.           if ((ch1==0x27)&&(ch2==0x65)&&(ch3==0x34)) { title[d++]='Σ';  a=1; }
  251.           if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x63)) { title[d++]='ⁿ';  a=1; }
  252.           if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x36)) { title[d++]='╓';  a=1; }
  253.           if ((ch1==0x27)&&(ch2==0x63)&&(ch3==0x34)) { title[d++]='─';  a=1; }
  254.           if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x63)) { title[d++]='▄';  a=1; }
  255. //          if (a==0)
  256. //              printf("!!!!! %04X %04X %04X %04X! \n",ch1,ch2,ch3,ch4);
  257.       } else {
  258.         title[d++]=ch;
  259.         s++;
  260.       }      
  261.   }
  262.   title[d]=0;
  263.  
  264.   // Section (2) becomes level 1 if it's an article.
  265.   if (DocumentStyle == LATEX_ARTICLE)
  266.     level --;
  267.  
  268.   if (level == 0) // Means we had a Chapter in an article, oops.
  269.     return;
  270.     
  271.   ResetContentsLevels(level);
  272.   
  273.   if (!title)
  274.     return;
  275.     
  276.   if (winHelp && winHelpContents && WinHelpContentsFile)
  277.   {
  278.     TexTopic *texTopic = (TexTopic *)TopicTable.Get(topicName);
  279.     if (texTopic)
  280.     {
  281.       // If a previous section at this level was a book, we *have* to have a
  282.       // book not a page, because of a bug in WHC (or WinHelp 4).
  283.       if (texTopic->hasChildren || level == 1 || ContentsLevels[level-1])
  284.       {
  285.         // At this level, we have a pointer to a further hierarchy.
  286.         // So we need a 'book' consisting of (say) Chapter 1.
  287.         fprintf(WinHelpContentsFile, "%d %s\n", level, title);
  288.  
  289.         // Then we have a 'page' consisting of the text for this chapter
  290.         fprintf(WinHelpContentsFile, "%d %s=%s\n", level+1, title, topicName);
  291.  
  292.         // Then we'll be writing out further pages or books at level + 1...
  293.  
  294.         // Remember that at this level, we had a book and *must* for the
  295.         // remainder of sections at this level.
  296.         ContentsLevels[level-1] = TRUE;
  297.       }
  298.       else
  299.       {
  300.         fprintf(WinHelpContentsFile, "%d %s=%s\n", level, title, topicName);
  301.       }
  302.     }
  303.     else
  304.     {
  305.       if (level == 1 || ContentsLevels[level-1])
  306.       {
  307.         // Always have a book at level 1
  308.         fprintf(WinHelpContentsFile, "%d %s\n", level, title);
  309.         fprintf(WinHelpContentsFile, "%d %s=%s\n", level+1, title, topicName);
  310.         ContentsLevels[level-1] = TRUE;
  311.       }
  312.       else
  313.         // Probably doesn't have children if it hasn't been added to the topic table
  314.         fprintf(WinHelpContentsFile, "%d %s=%s\n", level, title, topicName);
  315.     }
  316.   }
  317. }
  318.  
  319. void SplitIndexEntry(char *entry, char *buf1, char *buf2)
  320. {
  321.   int len = strlen(entry); int i = 0;
  322.   while ((i < len) && entry[i] != '!')
  323.   { buf1[i] = entry[i]; i ++; }
  324.   buf1[i] = 0; buf2[0] = 0; int j = 0;
  325.  
  326.   if (entry[i] == '!')
  327.   {
  328.     i ++;
  329.     while (i < len) { buf2[j] = entry[i]; i ++; j++; }
  330.     buf2[j] = 0;
  331.   }
  332. }
  333.  
  334. /*
  335.  * Output topic index entries in WinHelp RTF
  336.  *
  337.  */
  338. void GenerateKeywordsForTopic(char *topic)
  339. {
  340.   TexTopic *texTopic = (TexTopic *)TopicTable.Get(topic);
  341.   if (!texTopic)
  342.     return;
  343.  
  344.   wxStringList *list = texTopic->keywords;
  345.   if (list)
  346.   {
  347.     wxNode *node = list->First();
  348.     while (node)
  349.     {
  350.       char *s = (char *)node->Data();
  351.  
  352.       // Must separate out main entry form subentry (only 1 subentry allowed)
  353.       char buf1[100]; char buf2[100];
  354.       SplitIndexEntry(s, buf1, buf2);
  355.       
  356.       // Check for ':' which messes up index
  357.       unsigned int i;
  358.       for (i = 0; i < strlen(buf1) ; i++)
  359.         if (buf1[i] == ':')
  360.           buf1[i] = ' ';
  361.       for (i = 0; i < strlen(buf2) ; i++)
  362.         if (buf2[i] == ':')
  363.           buf2[i] = ' ';
  364.  
  365.       // {K} is a strange fix to prevent words beginning with K not
  366.       // being indexed properly
  367.       TexOutput("K{\\footnote {K} ");
  368.       TexOutput(buf1);
  369.       if (strlen(buf2) > 0)
  370.       {
  371.         // Output subentry
  372.         TexOutput(", ");
  373.         TexOutput(buf2);
  374.       }
  375.       TexOutput("}\n");
  376.       node = node->Next();
  377.     }
  378.   }
  379. }
  380.  
  381. /*
  382.  * Output index entry in linear RTF
  383.  *
  384.  */
  385.  
  386. void GenerateIndexEntry(char *entry)
  387. {
  388.   if (useWord)
  389.   {
  390.     char buf1[100]; char buf2[100];
  391.     SplitIndexEntry(entry, buf1, buf2);
  392.  
  393.     TexOutput("{\\xe\\v {");
  394.     TexOutput(buf1);
  395.     if (strlen(buf2) > 0)
  396.     {
  397.       TexOutput("\\:");
  398.       TexOutput(buf2);
  399.     }
  400.     TexOutput("}}");
  401.   }
  402. }
  403.  
  404.  /*
  405.   * Write a suitable RTF header.
  406.   *
  407.   */
  408.   
  409. void WriteColourTable(FILE *fd)
  410. {
  411.   fprintf(fd, "{\\colortbl");
  412.   wxNode *node = ColourTable.First();
  413.   while (node)
  414.   {
  415.     ColourTableEntry *entry = (ColourTableEntry *)node->Data();
  416.     fprintf(fd, "\\red%d\\green%d\\blue%d;\n", entry->red, entry->green, entry->blue);
  417.     node = node->Next();
  418.   }
  419.   fprintf(fd, "}");
  420. }
  421.  
  422. /*
  423.  * Write heading style
  424.  *
  425.  */
  426.  
  427. void WriteHeadingStyle(FILE *fd, int heading)
  428. {
  429.   switch (heading)
  430.   {
  431.     case 1:
  432.     {
  433.       fprintf(fd, "\\b\\fs%d", chapterFont*2);
  434.       break;
  435.     }
  436.     case 2:
  437.     {
  438.       fprintf(fd, "\\b\\fs%d", sectionFont*2);
  439.       break;
  440.     }
  441.     case 3:
  442.     {
  443.       fprintf(fd, "\\b\\fs%d", subsectionFont*2);
  444.       break;
  445.     }
  446.     case 4:
  447.     {
  448.       fprintf(fd, "\\b\\fs%d", subsectionFont*2);
  449.       break;
  450.     }
  451.     default:
  452.       break;
  453.   }
  454. }
  455.  
  456. void WriteRTFHeader(FILE *fd)
  457. {
  458.   fprintf(fd, "{\\rtf1\\%s \\deff0\n", RTFCharset);
  459.   fprintf(fd, "{\\fonttbl{\\f0\\froman Times New Roman;}{\\f1\\ftech Symbol;}{\\f2\\fswiss Arial;}\n");
  460.   fprintf(fd, "{\\f3\\fmodern Courier;}{\\f4\\ftech Wingdings;}{\\f5\\ftech Monotype Sorts;}\n}");
  461.   /*
  462.    * Style sheet
  463.    */
  464.   fprintf(fd, "{\\stylesheet{\\f2\\fs20 \\snext0 Normal;}\n");
  465.   // Headings
  466.   fprintf(fd, "{\\s1 "); WriteHeadingStyle(fd, 1); fprintf(fd, "\\sbasedon0\\snext0 heading 1;}\n");
  467.   fprintf(fd, "{\\s2 "); WriteHeadingStyle(fd, 2); fprintf(fd, "\\sbasedon0\\snext0 heading 2;}\n");
  468.   fprintf(fd, "{\\s3 "); WriteHeadingStyle(fd, 3); fprintf(fd, "\\sbasedon0\\snext0 heading 3;}\n");
  469.   fprintf(fd, "{\\s4 "); WriteHeadingStyle(fd, 4); fprintf(fd, "\\sbasedon0\\snext0 heading 4;}\n");
  470.   // Table of contents styles
  471.   fprintf(fd, "{\\s20\\sb300\\tqr\\tldot\\tx8640 \\b\\f2 \\sbasedon0\\snext0 toc 1;}\n");
  472.   
  473.   fprintf(fd, "{\\s21\\sb90\\tqr\\tldot\\li400\\tqr\\tx8640 \\f2\\fs20\\sbasedon0\\snext0 toc 2;}\n");
  474.   fprintf(fd, "{\\s22\\sb90\\tqr\\tldot\\li800\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 3;}\n");
  475.   fprintf(fd, "{\\s23\\sb90\\tqr\\tldot\\li1200\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 4;}\n");
  476.  
  477.   // Index styles
  478.   fprintf(fd, "{\\s30\\fi-200\\li200\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 1;}\n");
  479.   fprintf(fd, "{\\s31\\fi-200\\li400\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 2;}\n");
  480.   fprintf(fd, "{\\s32\\fi-200\\li600\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 3;}\n");
  481.   fprintf(fd, "{\\s33\\fi-200\\li800\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 4;}\n");
  482.   fprintf(fd, "{\\s35\\qc\\sb240\\sa120 \\b\\f2\\fs26 \\sbasedon0\\snext30 index heading;}\n");
  483.   fprintf(fd, "}\n");
  484.  
  485.   WriteColourTable(fd);
  486.   fprintf(fd, "\n\\ftnbj\\ftnrestart"); // Latex default is footnotes at bottom of page, not section.
  487.   fprintf(fd, "\n");
  488. }
  489.  
  490. void OutputNumberStyle(char *numberStyle)
  491. {
  492.   if (numberStyle)
  493.   {
  494.     if (strcmp(numberStyle, "arabic") == 0)
  495.     {
  496.       TexOutput("\\pgndec");
  497.     }
  498.     else if (strcmp(numberStyle, "roman") == 0)
  499.     {
  500.       TexOutput("\\pgnlcrm");
  501.     }
  502.     else if (strcmp(numberStyle, "Roman") == 0)
  503.     {
  504.       TexOutput("\\pgnucrm");
  505.     }
  506.     else if (strcmp(numberStyle, "alph") == 0)
  507.     {
  508.       TexOutput("\\pgnlcltr");
  509.     }
  510.     else if (strcmp(numberStyle, "Alph") == 0)
  511.     {
  512.       TexOutput("\\pgnucltr");
  513.     }
  514.   }
  515. }
  516.  
  517. /*
  518.  * Write a Windows help project file
  519.  */
  520.  
  521. bool WriteHPJ(char *filename)
  522. {
  523.   char hpjFilename[256];
  524.   char helpFile[50];
  525.   char rtfFile[50];
  526.   strcpy(hpjFilename, filename);
  527.   StripExtension(hpjFilename);
  528.   strcat(hpjFilename, ".hpj");
  529.  
  530.   strcpy(helpFile, FileNameFromPath(filename));
  531.   StripExtension(helpFile);
  532.   strcpy(rtfFile, helpFile);
  533.   strcat(helpFile, ".hlp");
  534.   strcat(rtfFile, ".rtf");
  535.   
  536.   FILE *fd = fopen(hpjFilename, "w");
  537.   if (!fd)
  538.     return FALSE;
  539.  
  540.   char *helpTitle = winHelpTitle;
  541.   if (!helpTitle)
  542.     helpTitle = "Untitled";
  543.     
  544.   wxString thePath = wxPathOnly(InputFile);
  545.   if (thePath.IsEmpty())
  546.     thePath = ".";
  547.   fprintf(fd, "[OPTIONS]\n");
  548.   fprintf(fd, "BMROOT=%s ; Assume that bitmaps are where the source is\n", thePath.c_str());
  549.   fprintf(fd, "TITLE=%s\n", helpTitle);
  550.   fprintf(fd, "CONTENTS=Contents\n");
  551.  
  552.   if (winHelpVersion > 3)
  553.   {
  554.     fprintf(fd, "; COMPRESS=12 Hall Zeck ; Max compression, but needs lots of memory\n");
  555.     fprintf(fd, "COMPRESS=8 Zeck\n");
  556.     fprintf(fd, "LCID=0x809 0x0 0x0 ;English (British)\n");
  557.     fprintf(fd, "HLP=.\\%s.hlp\n", wxFileNameFromPath(FileRoot));
  558.   }
  559.   else
  560.   {
  561.     fprintf(fd, "COMPRESS=HIGH\n");
  562.   }
  563.   fprintf(fd, "\n");
  564.  
  565.   if (winHelpVersion > 3)
  566.   {
  567.     fprintf(fd, "[WINDOWS]\n");
  568.     fprintf(fd, "Main=\"\",(553,102,400,600),20736,(r14876671),(r12632256),f3\n");
  569.     fprintf(fd, "\n");
  570.   }
  571.  
  572.   fprintf(fd, "[FILES]\n%s\n\n", rtfFile);
  573.   fprintf(fd, "[CONFIG]\n");
  574.   if (useUpButton)
  575.     fprintf(fd, "CreateButton(\"Up\", \"&Up\", \"JumpId(`%s', `Contents')\")\n", helpFile);
  576.   fprintf(fd, "BrowseButtons()\n\n");
  577.   fprintf(fd, "[MAP]\n\n[BITMAPS]\n\n");
  578.   fclose(fd);
  579.   return TRUE;
  580. }
  581.  
  582.  
  583. /*
  584.  * Given a TexChunk with a string value, scans through the string
  585.  * converting Latex-isms into RTF-isms, such as 2 newlines -> \par,
  586.  * and inserting spaces at the start of lines since in Latex, a newline
  587.  * implies a space, but not in RTF.
  588.  *
  589.  */
  590.  
  591. void ProcessText2RTF(TexChunk *chunk)
  592. {
  593.   bool changed = FALSE;
  594.   int ptr = 0;
  595.   int i = 0;
  596.   char ch = 1;
  597.   int len = strlen(chunk->value);
  598.   while (ch != 0)
  599.   {
  600.     ch = chunk->value[i];
  601.  
  602.     if (ch == 10)
  603.     {
  604.       if (inVerbatim)
  605.       {
  606.         BigBuffer[ptr] = 0; strcat(BigBuffer, "\\par\n"); ptr += 5;
  607.         i ++;
  608.         changed = TRUE;
  609.       }
  610.       else
  611.       {
  612.         // If the first character of the next line is ASCII,
  613.         // put a space in. Implicit in Latex, not in RTF.
  614.         /*
  615.           The reason this is difficult is that you don't really know
  616.           where a space would be appropriate. If you always put in a space
  617.           when you find a newline, unwanted spaces appear in the text.
  618.          */
  619.         if ((i > 0) && (len > i+1 && isascii(chunk->value[i+1]) &&
  620.                   !isspace(chunk->value[i+1])) ||
  621.             ((len > i+1 && chunk->value[i+1] == 13) &&
  622.              (len > i+2 && isascii(chunk->value[i+2]) &&
  623.               !isspace(chunk->value[i+2]))))
  624. //        if (TRUE)
  625.         {
  626.           // DOS files have a 13 after the 10
  627.           BigBuffer[ptr] = 10;
  628.           ptr ++;
  629.           i ++;
  630.           if (chunk->value[i] == 13)
  631.           {
  632.             BigBuffer[ptr] = 13;
  633.             ptr ++;
  634.             i ++;
  635.           }
  636.  
  637.           BigBuffer[ptr] = ' ';
  638.           ptr ++;
  639.  
  640.           // Note that the actual ASCII character seen is dealt with in the next
  641.           // iteration
  642.           changed = TRUE;
  643.         }
  644.         else
  645.         {
  646.           BigBuffer[ptr] = ch;
  647.           i ++;
  648.         }
  649.       }
  650.     }
  651.     else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
  652.     {
  653.       BigBuffer[ptr] = '"'; ptr ++;
  654.       i += 2;
  655.       changed = TRUE;
  656.     }
  657.     else if (!inVerbatim && ch == '`') // Change ` to '
  658.     {
  659.       BigBuffer[ptr] = 39; ptr ++;
  660.       i += 1;
  661.       changed = TRUE;
  662.     }
  663.     else if (inVerbatim && ch == '\\') // Change backslash to two backslashes
  664.     {
  665.       BigBuffer[ptr] = '\\'; ptr ++;
  666.       BigBuffer[ptr] = '\\'; ptr ++;
  667.       i += 1;
  668.       changed = TRUE;
  669.     }
  670.     else if (inVerbatim && (ch == '{' || ch == '}')) // Escape the curley bracket
  671.     {
  672.       BigBuffer[ptr] = '\\'; ptr ++;
  673.       BigBuffer[ptr] = ch; ptr ++;
  674.       i += 1;
  675.       changed = TRUE;
  676.     }
  677.     else
  678.     {
  679.       BigBuffer[ptr] = ch;
  680.       i ++;
  681.       ptr ++;
  682.     }
  683.   }
  684.   BigBuffer[ptr] = 0;
  685.  
  686.   if (changed)
  687.   {
  688.     delete[] chunk->value;
  689.     chunk->value = copystring(BigBuffer);
  690.   }
  691. }
  692.  
  693. /*
  694.  * Scan through all chunks starting from the given one,
  695.  * calling ProcessText2RTF to convert Latex-isms to RTF-isms.
  696.  * This should be called after Tex2Any has parsed the file,
  697.  * and before TraverseDocument is called.
  698.  *
  699.  */
  700.  
  701. void Text2RTF(TexChunk *chunk)
  702. {
  703.   Tex2RTFYield();
  704.   if (stopRunning) return;
  705.  
  706.   switch (chunk->type)
  707.   {
  708.     case CHUNK_TYPE_MACRO:
  709.     {
  710.       TexMacroDef *def = chunk->def;
  711.       if (def && def->ignore)
  712.         return;
  713.  
  714.       if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
  715.         inVerbatim = TRUE;
  716.  
  717.       wxNode *node = chunk->children.First();
  718.       while (node)
  719.       {
  720.         TexChunk *child_chunk = (TexChunk *)node->Data();
  721.         Text2RTF(child_chunk);
  722.         node = node->Next();
  723.       }
  724.  
  725.       if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
  726.         inVerbatim = FALSE;
  727.  
  728.       break;
  729.     }
  730.     case CHUNK_TYPE_ARG:
  731.     {
  732.       wxNode *node = chunk->children.First();
  733.       while (node)
  734.       {
  735.         TexChunk *child_chunk = (TexChunk *)node->Data();
  736.         Text2RTF(child_chunk);
  737.         node = node->Next();
  738.       }
  739.  
  740.       break;
  741.     }
  742.     case CHUNK_TYPE_STRING:
  743.     {
  744.       if (chunk->value)
  745.         ProcessText2RTF(chunk);
  746.       break;
  747.     }
  748.   }
  749. }
  750.  
  751. /*
  752.  * Not used yet
  753.  *
  754.  */
  755.  
  756. char browseBuf[10];
  757. static long browseId = 0;
  758. char *GetBrowseString(void)
  759. {
  760.   char buf[10];
  761.   browseId ++;
  762.   sprintf(buf, "%ld", browseId);
  763.   int noZeroes = 5-strlen(buf);
  764.   strcpy(browseBuf, "browse");
  765.   for (int i = 0; i < noZeroes; i++)
  766.     strcat(browseBuf, "0");
  767.   strcat(browseBuf, buf);
  768.   return browseBuf;
  769. }
  770.  
  771. /*
  772.  * Keeping track of environments to restore the styles after \pard.
  773.  * Push strings like "\qc" onto stack.
  774.  *
  775.  */
  776.  
  777. void PushEnvironmentStyle(char *style)
  778. {
  779.   environmentStack.Add(style);
  780. }
  781.  
  782. void PopEnvironmentStyle(void)
  783. {
  784.   wxNode *node = environmentStack.Last();
  785.   if (node)
  786.   {
  787.     char *val = (char *)node->Data();
  788.     delete[] val;
  789.     delete node;
  790.   }
  791. }
  792.  
  793. // Write out the styles, most recent first.
  794. void WriteEnvironmentStyles(void)
  795. {
  796.   wxNode *node = environmentStack.Last();
  797.   while (node)
  798.   {
  799.     char *val = (char *)node->Data();
  800.     TexOutput(val);
  801.     node = node->Next();
  802.   }
  803.   if (!inTabular && (ParIndent > 0) && (forbidParindent == 0))
  804.   {
  805.     char buf[15];
  806.     sprintf(buf, "\\fi%d", ParIndent*20); // Convert points to TWIPS
  807.     TexOutput(buf);
  808.   }
  809.   if (environmentStack.Number() > 0 || (ParIndent > 0))
  810.     TexOutput("\n");
  811. }
  812.  
  813.  
  814. /*
  815.  * Output a header
  816.  *
  817.  */
  818.  
  819. void OutputRTFHeaderCommands(void)
  820. {
  821.   char buf[300];
  822.   if (PageStyle && strcmp(PageStyle, "plain") == 0)
  823.   {
  824.     TexOutput("{\\headerl }{\\headerr }");
  825.   }
  826.   else if (PageStyle && strcmp(PageStyle, "empty") == 0)
  827.   {
  828.     TexOutput("{\\headerl }{\\headerr }");
  829.   }
  830.   else if (PageStyle && strcmp(PageStyle, "headings") == 0)
  831.   {
  832.     // Left header
  833.     TexOutput("{\\headerl\\fi0 ");
  834.  
  835.     if (headerRule)
  836.       TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  837.  
  838.     TexOutput("{\\i \\qr ");
  839.     if (DocumentStyle == LATEX_ARTICLE)
  840.     {
  841.       sprintf(buf, "SECTION %d", sectionNo);
  842.       TexOutput(buf);
  843.     }
  844.     else
  845.     {
  846.       sprintf(buf, "CHAPTER %d: ", chapterNo);
  847.       TexOutput(buf);
  848.     }
  849.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  850.     TexOutput("}\\par\\pard}");
  851.  
  852.     // Right header
  853.     TexOutput("{\\headerr\\fi0 ");
  854.  
  855.     if (headerRule)
  856.       TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  857.  
  858.     TexOutput("{\\i \\qc ");
  859.     if (DocumentStyle == LATEX_ARTICLE)
  860.     {
  861.       sprintf(buf, "SECTION %d", sectionNo);
  862.       TexOutput(buf);
  863.     }
  864.     else
  865.     {
  866.       sprintf(buf, "CHAPTER %d", chapterNo);
  867.       TexOutput(buf);
  868.     }
  869.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  870.     TexOutput("}\\par\\pard}");
  871.   }
  872.   else
  873.   {
  874.     int oldForbidResetPar = forbidResetPar;
  875.     forbidResetPar = 0;
  876.     
  877.     if (LeftHeaderEven || CentreHeaderEven || RightHeaderEven)
  878.     {
  879.       TexOutput("{\\headerl\\fi0 ");
  880.  
  881.       if (headerRule)
  882.         TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  883.  
  884.       if (LeftHeaderEven)
  885.       {
  886.         if (!CentreHeaderEven && !RightHeaderEven)
  887.           TexOutput("\\ql ");
  888.         TraverseChildrenFromChunk(LeftHeaderEven);
  889.       }
  890.       if (CentreHeaderEven)
  891.       {
  892.         if (!LeftHeaderEven && !RightHeaderEven)
  893.           TexOutput("\\qc ");
  894.         else
  895.           TexOutput("\\tab\\tab\\tab ");
  896.         TraverseChildrenFromChunk(CentreHeaderEven);
  897.       }
  898.       if (RightHeaderEven)
  899.       {
  900.         if (!LeftHeaderEven && !CentreHeaderEven)
  901.           TexOutput("\\qr ");
  902.         else
  903.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  904.         TraverseChildrenFromChunk(RightHeaderEven);
  905.       }
  906.       TexOutput("\\par\\pard}");
  907.     }
  908.  
  909.     if (LeftHeaderOdd || CentreHeaderOdd || RightHeaderOdd)
  910.     {
  911.       TexOutput("{\\headerr\\fi0 ");
  912.  
  913.       if (headerRule)
  914.         TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  915.  
  916.       if (LeftHeaderOdd)
  917.       {
  918.         if (!CentreHeaderOdd && !RightHeaderOdd)
  919.           TexOutput("\\ql ");
  920.         TraverseChildrenFromChunk(LeftHeaderOdd);
  921.       }
  922.       if (CentreHeaderOdd)
  923.       {
  924.         if (!LeftHeaderOdd && !RightHeaderOdd)
  925.           TexOutput("\\qc ");
  926.         else
  927.           TexOutput("\\tab\\tab\\tab ");
  928.         TraverseChildrenFromChunk(CentreHeaderOdd);
  929.       }
  930.       if (RightHeaderOdd)
  931.       {
  932.         if (!LeftHeaderOdd && !CentreHeaderOdd)
  933.           TexOutput("\\qr ");
  934.         else
  935.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  936.         TraverseChildrenFromChunk(RightHeaderOdd);
  937.       }
  938.       TexOutput("\\par\\pard}");
  939.     }
  940.     // As an approximation, don't put a header on the first page of a section.
  941.     // This may not always be desired, but it's a reasonable guess.
  942.     TexOutput("{\\headerf }");
  943.  
  944.     forbidResetPar = oldForbidResetPar;
  945.   }
  946. }
  947.  
  948. void OutputRTFFooterCommands(void)
  949. {
  950.   if (PageStyle && strcmp(PageStyle, "plain") == 0)
  951.   {
  952.     TexOutput("{\\footerl\\fi0 ");
  953.     if (footerRule)
  954.       TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  955.     TexOutput("{\\qc ");
  956.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  957.     TexOutput("}\\par\\pard}");
  958.  
  959.     TexOutput("{\\footerr\\fi0 ");
  960.     if (footerRule)
  961.       TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  962.     TexOutput("{\\qc ");
  963.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  964.     TexOutput("}\\par\\pard}");
  965.   }
  966.   else if (PageStyle && strcmp(PageStyle, "empty") == 0)
  967.   {
  968.     TexOutput("{\\footerl }{\\footerr }");
  969.   }
  970.   else if (PageStyle && strcmp(PageStyle, "headings") == 0)
  971.   {
  972.     TexOutput("{\\footerl }{\\footerr }");
  973.   }
  974.   else
  975.   {
  976.     if (LeftFooterEven || CentreFooterEven || RightFooterEven)
  977.     {
  978.       TexOutput("{\\footerl\\fi0 ");
  979.       if (footerRule)
  980.         TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  981.       if (LeftFooterEven)
  982.       {
  983.         if (!CentreFooterEven && !RightFooterEven)
  984.           TexOutput("\\ql ");
  985.         TraverseChildrenFromChunk(LeftFooterEven);
  986.       }
  987.       if (CentreFooterEven)
  988.       {
  989.         if (!LeftFooterEven && !RightFooterEven)
  990.           TexOutput("\\qc ");
  991.         else
  992.           TexOutput("\\tab\\tab\\tab ");
  993.         TraverseChildrenFromChunk(CentreFooterEven);
  994.       }
  995.       if (RightFooterEven)
  996.       {
  997.         if (!LeftFooterEven && !CentreFooterEven)
  998.           TexOutput("\\qr ");
  999.         else
  1000.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  1001.         TraverseChildrenFromChunk(RightFooterEven);
  1002.       }
  1003.       TexOutput("\\par\\pard}");
  1004.     }
  1005.  
  1006.     if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
  1007.     {
  1008.       TexOutput("{\\footerr\\fi0 ");
  1009.       if (footerRule)
  1010.         TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  1011.       if (LeftFooterOdd)
  1012.       {
  1013.         if (!CentreFooterOdd && !RightFooterOdd)
  1014.           TexOutput("\\ql ");
  1015.         TraverseChildrenFromChunk(LeftFooterOdd);
  1016.       }
  1017.       if (CentreFooterOdd)
  1018.       {
  1019.         if (!LeftFooterOdd && !RightFooterOdd)
  1020.           TexOutput("\\qc ");
  1021.         else
  1022.           TexOutput("\\tab\\tab\\tab ");
  1023.         TraverseChildrenFromChunk(CentreFooterOdd);
  1024.       }
  1025.       if (RightFooterOdd)
  1026.       {
  1027.         if (!LeftFooterOdd && !CentreFooterOdd)
  1028.           TexOutput("\\qr ");
  1029.         else
  1030.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  1031.         TraverseChildrenFromChunk(RightFooterOdd);
  1032.       }
  1033.       TexOutput("\\par\\pard}");
  1034.     }
  1035.  
  1036.     // As an approximation, put a footer on the first page of a section.
  1037.     // This may not always be desired, but it's a reasonable guess.
  1038.     if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
  1039.     {
  1040.       TexOutput("{\\footerf\\fi0 ");
  1041.       if (LeftFooterOdd)
  1042.       {
  1043.         if (!CentreFooterOdd && !RightFooterOdd)
  1044.           TexOutput("\\ql ");
  1045.         TraverseChildrenFromChunk(LeftFooterOdd);
  1046.       }
  1047.       if (CentreFooterOdd)
  1048.       {
  1049.         if (!LeftFooterOdd && !RightFooterOdd)
  1050.           TexOutput("\\qc ");
  1051.         else
  1052.           TexOutput("\\tab\\tab\\tab ");
  1053.         TraverseChildrenFromChunk(CentreFooterOdd);
  1054.       }
  1055.       if (RightFooterOdd)
  1056.       {
  1057.         if (!LeftFooterOdd && !CentreFooterOdd)
  1058.           TexOutput("\\qr ");
  1059.         else
  1060.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  1061.         TraverseChildrenFromChunk(RightFooterOdd);
  1062.       }
  1063.       TexOutput("\\par\\pard}");
  1064.     }
  1065.   }
  1066. }
  1067.  
  1068. // Called on start/end of macro examination
  1069. void RTFOnMacro(int macroId, int no_args, bool start)
  1070. {
  1071. /*
  1072.   char tmpBuf[40];
  1073.   sprintf(tmpBuf, "%d (%d)", macroId, (int)start);
  1074.   OutputDebugString("RTFOnMacro Start "); OutputDebugString(tmpBuf);
  1075.   OutputDebugString("\n"); wxYield();
  1076. */
  1077.  
  1078.   // ltLABEL is included here because after a section but BEFORE
  1079.   // the label is seen, a new paragraph is issued. Don't upset this by
  1080.   // immediately forgetting we've done it.
  1081.   if (start && (macroId != ltPAR && macroId != ltITEMIZE &&
  1082.                         macroId != ltENUMERATE && macroId != ltDESCRIPTION &&
  1083.                         macroId != ltVERBATIM && macroId != ltLABEL &&
  1084.                         macroId != ltSETHEADER && macroId != ltSETFOOTER &&
  1085.                         macroId != ltPAGENUMBERING &&
  1086.                         (forbidResetPar == 0)))
  1087.   {
  1088.     issuedNewParagraph = 0;
  1089.   }
  1090.  
  1091.   char buf[300];
  1092.   switch (macroId)
  1093.   {
  1094.   case ltCHAPTER:
  1095.   case ltCHAPTERSTAR:
  1096.   case ltCHAPTERHEADING:
  1097.   case ltCHAPTERHEADINGSTAR:
  1098.   {
  1099.     if (!start)
  1100.     {
  1101.       sectionNo = 0;
  1102.       figureNo = 0;
  1103.       tableNo = 0;
  1104.       subsectionNo = 0;
  1105.       subsubsectionNo = 0;
  1106.       footnoteCount = 0;
  1107.  
  1108.       if (macroId != ltCHAPTERSTAR && macroId != ltCHAPTERHEADINGSTAR)
  1109.         chapterNo ++;
  1110.  
  1111.       char *topicName = FindTopicName(GetNextChunk());
  1112.       SetCurrentChapterName(topicName);
  1113.  
  1114.       if (winHelpContents && winHelp && !InPopups())
  1115.       {
  1116.         OutputCurrentSectionToString(wxTex2RTFBuffer);
  1117.         WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 1);
  1118.       }
  1119.       AddTexRef(topicName, NULL, ChapterNameString, chapterNo);
  1120.  
  1121.       if (winHelp)
  1122.       {
  1123.         if (!InPopups())
  1124.           fprintf(Contents, "\n{\\uldb ");
  1125.         fprintf(Chapters, "\\page");
  1126.         fprintf(Chapters, "\n${\\footnote ");
  1127.         if (!InPopups())
  1128.           SetCurrentOutputs(Contents, Chapters);
  1129.         else
  1130.           SetCurrentOutput(Chapters);
  1131.       }
  1132.       else
  1133.       {
  1134.         fprintf(Chapters, "\\sect\\pgncont\\titlepg\n");
  1135.  
  1136.         // If a non-custom page style, we generate the header now.
  1137.         if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
  1138.                           strcmp(PageStyle, "empty") == 0 ||
  1139.                           strcmp(PageStyle, "headings") == 0))
  1140.         {
  1141.           OutputRTFHeaderCommands();
  1142.           OutputRTFFooterCommands();
  1143.         }
  1144.         
  1145.         // Need to reset the current numbering style, or RTF forgets it.
  1146.         SetCurrentOutput(Chapters);
  1147.         OutputNumberStyle(currentNumberStyle);
  1148.  
  1149.         SetCurrentOutput(Contents);
  1150.  
  1151.         if (!InPopups())
  1152.         {
  1153.           if (macroId == ltCHAPTER)
  1154.           {
  1155.             // Section
  1156.             fprintf(Contents, "\\par\n\\pard{\\b %d\\tab ", chapterNo);
  1157.           }
  1158.           else if (macroId == ltCHAPTERHEADING)
  1159.           {
  1160.             fprintf(Contents, "\\par\n\\pard{\\b ");
  1161.           }
  1162.           else SetCurrentOutput(NULL); // No entry in table of contents
  1163.         }
  1164.       }
  1165.   
  1166.       startedSections = TRUE;
  1167.  
  1168.       // Output heading to contents page
  1169.       if (!InPopups())
  1170.       {
  1171.         OutputCurrentSection();
  1172.       
  1173.         if (winHelp)
  1174.           fprintf(Contents, "}{\\v %s}\\par\\pard\n", topicName);
  1175.         else if ((macroId == ltCHAPTER) || (macroId == ltCHAPTERHEADING))
  1176.           fprintf(Contents, "}\\par\\par\\pard\n");
  1177.  
  1178.         // From here, just output to chapter
  1179.         SetCurrentOutput(Chapters);
  1180.       }
  1181.      
  1182.       if (winHelp)
  1183.       {
  1184.         fprintf(Chapters, "}\n#{\\footnote %s}\n", topicName);
  1185.         fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
  1186.         
  1187.         OutputSectionKeyword(Chapters);
  1188.  
  1189.         GenerateKeywordsForTopic(topicName);
  1190.         if (useUpButton)
  1191.         {
  1192.           // If we're generating a .cnt file, we don't want to be able
  1193.           // jump up to the old-style contents page, so disable it.
  1194.           if (winHelpContents)
  1195.             fprintf(Chapters, "!{\\footnote DisableButton(\"Up\")}\n");
  1196.           else
  1197.             fprintf(Chapters, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1198.                FileNameFromPath(FileRoot), "Contents");
  1199.         }
  1200.       }
  1201.  
  1202.       if (!InPopups())
  1203.       {
  1204.       char *styleCommand = "";
  1205.       if (!winHelp && useHeadingStyles && (macroId == ltCHAPTER || macroId == ltCHAPTERHEADING || macroId == ltCHAPTERHEADINGSTAR))
  1206.         styleCommand = "\\s1";
  1207.       fprintf(Chapters, "\\pard{%s", ((winHelp && !InPopups()) ? "\\keepn\\sa140\\sb140" : styleCommand));
  1208.       WriteHeadingStyle(Chapters, 1);  fprintf(Chapters, " ");
  1209.       if (!winHelp)
  1210.       {
  1211.         if (macroId == ltCHAPTER)
  1212.         {
  1213.           if (useWord)
  1214. //            fprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, chapterNo,
  1215.             fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
  1216.           else
  1217.             fprintf(Chapters, "%d. ", chapterNo);
  1218.         }
  1219.         else if ( useWord )
  1220.         {
  1221.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
  1222.         }
  1223.       }
  1224.       OutputCurrentSection();
  1225.       TexOutput("\\par\\pard}\\par\n");
  1226.       }
  1227.       issuedNewParagraph = 2;
  1228.     }
  1229.     break;
  1230.   }
  1231.   case ltSECTION:
  1232.   case ltSECTIONSTAR:
  1233.   case ltSECTIONHEADING:
  1234.   case ltSECTIONHEADINGSTAR:
  1235.   case ltGLOSS:
  1236.   {
  1237.     FILE *jumpFrom;
  1238.     if (DocumentStyle == LATEX_ARTICLE)
  1239.       jumpFrom = Contents;
  1240.     else
  1241.       jumpFrom = Chapters;
  1242.  
  1243.     if (!start)
  1244.     {
  1245.       subsectionNo = 0;
  1246.       subsubsectionNo = 0;
  1247.       if (DocumentStyle == LATEX_ARTICLE)
  1248.         footnoteCount = 0;
  1249.  
  1250.       if (macroId != ltSECTIONSTAR && macroId != ltSECTIONHEADINGSTAR)
  1251.         sectionNo ++;
  1252.  
  1253.       char *topicName = FindTopicName(GetNextChunk());
  1254.       SetCurrentSectionName(topicName);
  1255.       NotifyParentHasChildren(1);
  1256.       if (winHelpContents && winHelp && !InPopups())
  1257.       {
  1258.         OutputCurrentSectionToString(wxTex2RTFBuffer);
  1259.         WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 2);
  1260.       }
  1261.       AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo);
  1262.  
  1263.       if (winHelp)
  1264.       {
  1265.         SetCurrentOutputs(jumpFrom, Sections);
  1266.         // Newline for a new section if this is an article
  1267.         if ((DocumentStyle == LATEX_ARTICLE) &&
  1268.             ((macroId == ltSECTION) || (macroId == ltSECTIONSTAR) || (macroId == ltSECTIONHEADINGSTAR)))
  1269.           fprintf(Sections, "\\page\n");
  1270.  
  1271.         if (!InPopups())
  1272.           fprintf(jumpFrom, "\n{\\uldb ");
  1273.       }
  1274.       else
  1275.       {
  1276.         if (DocumentStyle == LATEX_ARTICLE)
  1277.         {
  1278.           TexOutput("\\sect\\pgncont\n");
  1279.           // If a non-custom page style, we generate the header now.
  1280.           if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
  1281.                             strcmp(PageStyle, "empty") == 0 ||
  1282.                             strcmp(PageStyle, "headings") == 0))
  1283.           {
  1284.             OutputRTFHeaderCommands();
  1285.             OutputRTFFooterCommands();
  1286.           }
  1287.         }
  1288.         SetCurrentOutput(Contents);
  1289.  
  1290.         if (macroId == ltSECTION)
  1291.         {
  1292.           if (!InPopups())
  1293.           {
  1294.             if (DocumentStyle == LATEX_REPORT)
  1295.               fprintf(Contents, "\n\\pard{\\tab %d.%d\\tab ", chapterNo, sectionNo);
  1296.             else
  1297.               fprintf(Contents, "\\par\n\\pard{\\b %d\\tab ", sectionNo);
  1298.           }
  1299.         }
  1300.         else if (macroId == ltSECTIONHEADING)
  1301.         {
  1302.           if (!InPopups())
  1303.           {
  1304.             if (DocumentStyle == LATEX_REPORT)
  1305.               fprintf(Contents, "\n\\pard{\\tab "); //, chapterNo, sectionNo);
  1306.             else
  1307.               fprintf(Contents, "\\par\n\\pard{\\b "); //, sectionNo);
  1308.           }
  1309.         }
  1310.         else SetCurrentOutput(NULL);
  1311.       } 
  1312.  
  1313.       if (startedSections)
  1314.       {
  1315.         if (winHelp)
  1316.           fprintf(Sections, "\\page\n");
  1317.       }
  1318.       startedSections = TRUE;
  1319.  
  1320.       if (winHelp)
  1321.         fprintf(Sections, "\n${\\footnote ");
  1322.  
  1323.       // Output heading to contents page
  1324.       if (!InPopups())
  1325.         OutputCurrentSection();
  1326.  
  1327.       if (winHelp)
  1328.       {
  1329.         if (!InPopups())
  1330.           fprintf(jumpFrom, "}{\\v %s}\\par\\pard\n", topicName);
  1331.       }
  1332.       else if ((macroId != ltSECTIONSTAR) && (macroId != ltGLOSS))
  1333.       {
  1334.         if (DocumentStyle == LATEX_REPORT)
  1335.           fprintf(Contents, "}\\par\\pard\n");
  1336.         else
  1337.           fprintf(Contents, "}\\par\\par\\pard\n");
  1338.       }
  1339.         
  1340.       SetCurrentOutput(winHelp ? Sections : Chapters);
  1341.  
  1342.       if (winHelp)
  1343.       {
  1344.         fprintf(Sections, "}\n#{\\footnote %s}\n", topicName);
  1345.         fprintf(Sections, "+{\\footnote %s}\n", GetBrowseString());
  1346.         OutputSectionKeyword(Sections);
  1347.         GenerateKeywordsForTopic(topicName);
  1348.         if (useUpButton)
  1349.         {
  1350.           if (DocumentStyle == LATEX_ARTICLE)
  1351.           {
  1352.             fprintf(Sections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1353.                FileNameFromPath(FileRoot), "Contents");
  1354.           }
  1355.           else if (CurrentChapterName)
  1356.           {
  1357.             fprintf(Sections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1358.                FileNameFromPath(FileRoot), CurrentChapterName);
  1359.           }
  1360.         }
  1361.       }
  1362.  
  1363.       if (!InPopups())
  1364.       {
  1365.       char *styleCommand = "";
  1366.       if (!winHelp && useHeadingStyles && (macroId != ltSECTIONSTAR))
  1367.       {
  1368.         if (DocumentStyle == LATEX_ARTICLE)
  1369.           styleCommand = "\\s1";
  1370.         else
  1371.           styleCommand = "\\s2";
  1372.       }
  1373.       char *keep = "";
  1374.       if (winHelp && (macroId != ltGLOSS) && !InPopups())
  1375.         keep = "\\keepn\\sa140\\sb140";
  1376.         
  1377.       fprintf(winHelp ? Sections : Chapters, "\\pard{%s%s",
  1378.          keep, styleCommand);
  1379.  
  1380.       WriteHeadingStyle((winHelp ? Sections : Chapters),
  1381.                         (DocumentStyle == LATEX_ARTICLE ? 1 : 2));
  1382.       fprintf(winHelp ? Sections : Chapters, " ");
  1383.  
  1384.       if (!winHelp)
  1385.       {
  1386.         if ((macroId != ltSECTIONSTAR) && (macroId != ltSECTIONHEADINGSTAR) && (macroId != ltGLOSS))
  1387.         {
  1388.           if (DocumentStyle == LATEX_REPORT)
  1389.           {
  1390.             if (useWord)
  1391. //              fprintf(Chapters, "{\\bkmkstart %s}%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo,
  1392.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
  1393.                   topicName);
  1394.             else
  1395.               fprintf(Chapters, "%d.%d. ", chapterNo, sectionNo);
  1396.           }
  1397.           else
  1398.           {
  1399.             if (useWord)
  1400. //              fprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, sectionNo,
  1401.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
  1402.                  topicName);
  1403.             else
  1404.               fprintf(Chapters, "%d. ", sectionNo);
  1405.           }
  1406.         }
  1407.         else if ( useWord )
  1408.         {
  1409.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
  1410.         }
  1411.       }
  1412.       OutputCurrentSection();
  1413.       TexOutput("\\par\\pard}\\par\n");
  1414.       }
  1415.       issuedNewParagraph = 2;
  1416.     }
  1417.     break;
  1418.   }
  1419.   case ltSUBSECTION:
  1420.   case ltSUBSECTIONSTAR:
  1421.   case ltMEMBERSECTION:
  1422.   case ltFUNCTIONSECTION:
  1423.   {
  1424.     if (!start)
  1425.     {
  1426.       if (winHelp && !Sections)
  1427.       {
  1428.         OnError("You cannot have a subsection before a section!");
  1429.       }
  1430.       else
  1431.       {
  1432.       subsubsectionNo = 0;
  1433.  
  1434.       if (macroId != ltSUBSECTIONSTAR)
  1435.         subsectionNo ++;
  1436.  
  1437.       char *topicName = FindTopicName(GetNextChunk());
  1438.       SetCurrentSubsectionName(topicName);
  1439.       NotifyParentHasChildren(2);
  1440.       if (winHelpContents && winHelp && !InPopups())
  1441.       {
  1442.         OutputCurrentSectionToString(wxTex2RTFBuffer);
  1443.         WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 3);
  1444.       }
  1445.       AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo);
  1446.  
  1447.       if (winHelp)
  1448.       {
  1449.         SetCurrentOutputs(Sections, Subsections);
  1450.         SetCurrentOutputs(Sections, Subsections);
  1451.         if (!InPopups())
  1452.           fprintf(Sections, "\n{\\uldb ");
  1453.       }
  1454.       else
  1455.       {
  1456.         if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1457.             (macroId != ltFUNCTIONSECTION))
  1458.         {
  1459.           SetCurrentOutput(Contents);
  1460.           if (DocumentStyle == LATEX_REPORT)
  1461.             fprintf(Contents, "\n\\pard\\tab\\tab %d.%d.%d\\tab ", chapterNo, sectionNo, subsectionNo);
  1462.           else
  1463.             fprintf(Contents, "\n\\pard\\tab %d.%d\\tab ", sectionNo, subsectionNo);
  1464.         } else SetCurrentOutput(NULL);
  1465.       }
  1466.       if (startedSections)
  1467.       {
  1468.         if (winHelp)
  1469.         {
  1470.           if (!InPopups())
  1471.             fprintf(Subsections, "\\page\n");
  1472.         }
  1473.         else
  1474.           fprintf(Chapters, "\\par\n");
  1475.       }
  1476.       startedSections = TRUE;
  1477.  
  1478.       if (winHelp)
  1479.         fprintf(Subsections, "\n${\\footnote ");
  1480.  
  1481.       // Output to contents page
  1482.       if (!InPopups())
  1483.         OutputCurrentSection();
  1484.  
  1485.       if (winHelp)
  1486.       {
  1487.         if (!InPopups())
  1488.           fprintf(Sections, "}{\\v %s}\\par\\pard\n", topicName);
  1489.       }
  1490.       else if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1491.          (macroId != ltFUNCTIONSECTION))
  1492.         fprintf(Contents, "\\par\\pard\n");
  1493.  
  1494.       SetCurrentOutput(winHelp ? Subsections : Chapters);
  1495.       if (winHelp)
  1496.       {
  1497.         fprintf(Subsections, "}\n#{\\footnote %s}\n", topicName);
  1498.         fprintf(Subsections, "+{\\footnote %s}\n", GetBrowseString());
  1499.         OutputSectionKeyword(Subsections);
  1500.         GenerateKeywordsForTopic(topicName);
  1501.         if (useUpButton && CurrentSectionName)
  1502.         {
  1503.           fprintf(Subsections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1504.              FileNameFromPath(FileRoot), CurrentSectionName);
  1505.         }
  1506.       }
  1507.       if (!winHelp && indexSubsections && useWord)
  1508.       {
  1509.         // Insert index entry for this subsection
  1510.         TexOutput("{\\xe\\v {");
  1511.         OutputCurrentSection();
  1512.         TexOutput("}}");
  1513.       }
  1514.  
  1515.       if (!InPopups())
  1516.       {
  1517.       char *styleCommand = "";
  1518.       if (!winHelp && useHeadingStyles && (macroId != ltSUBSECTIONSTAR))
  1519.       {
  1520.         if (DocumentStyle == LATEX_ARTICLE)
  1521.           styleCommand = "\\s2";
  1522.         else
  1523.           styleCommand = "\\s3";
  1524.       }
  1525.       char *keep = "";
  1526.       if (winHelp && !InPopups())
  1527.         keep = "\\keepn\\sa140\\sb140";
  1528.  
  1529.       fprintf(winHelp ? Subsections : Chapters, "\\pard{%s%s",
  1530.          keep, styleCommand);
  1531.  
  1532.       WriteHeadingStyle((winHelp ? Subsections : Chapters),
  1533.                         (DocumentStyle == LATEX_ARTICLE ? 2 : 3));
  1534.       fprintf(winHelp ? Subsections : Chapters, " ");
  1535.  
  1536.       if (!winHelp)
  1537.       {
  1538.         if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1539.          (macroId != ltFUNCTIONSECTION))
  1540.         {
  1541.           if (DocumentStyle == LATEX_REPORT)
  1542.           {
  1543.             if (useWord)
  1544. //              fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo, subsectionNo,
  1545.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
  1546.                        topicName);
  1547.             else
  1548.               fprintf(Chapters, "%d.%d.%d. ", chapterNo, sectionNo, subsectionNo);
  1549.           }
  1550.           else
  1551.           {
  1552.             if (useWord)
  1553. //              fprintf(Chapters, "{\\bkmkstart %s}%d.%d{\\bkmkend %s}. ", topicName, sectionNo, subsectionNo,
  1554.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
  1555.                        topicName);
  1556.             else
  1557.               fprintf(Chapters, "%d.%d. ", sectionNo, subsectionNo);
  1558.           }
  1559.         }
  1560.         else if ( useWord )
  1561.         {
  1562.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
  1563.         }
  1564.       }
  1565.       OutputCurrentSection(); // Repeat section header
  1566.       TexOutput("\\par\\pard}\\par\n");
  1567.       }
  1568.       issuedNewParagraph = 2;
  1569.     }
  1570.     }
  1571.     break;
  1572.   }
  1573.   case ltSUBSUBSECTION:
  1574.   case ltSUBSUBSECTIONSTAR:
  1575.   {
  1576.     if (!start)
  1577.     {
  1578.       if (winHelp && !Subsections)
  1579.       {
  1580.         OnError("You cannot have a subsubsection before a subsection!");
  1581.       }
  1582.       else
  1583.       {
  1584.       if (macroId != ltSUBSUBSECTIONSTAR)
  1585.         subsubsectionNo ++;
  1586.  
  1587.       char *topicName = FindTopicName(GetNextChunk());
  1588.       SetCurrentTopic(topicName);
  1589.       NotifyParentHasChildren(3);
  1590.       if (winHelpContents && winHelp)
  1591.       {
  1592.         OutputCurrentSectionToString(wxTex2RTFBuffer);
  1593.         WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 4);
  1594.       }
  1595.       AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo, subsubsectionNo);
  1596.  
  1597.       if (winHelp)
  1598.       {
  1599.         SetCurrentOutputs(Subsections, Subsubsections);
  1600.         fprintf(Subsections, "\n{\\uldb ");
  1601.       }
  1602.       else
  1603.       {
  1604.         if (macroId != ltSUBSUBSECTIONSTAR)
  1605.         {
  1606.           if (DocumentStyle == LATEX_ARTICLE)
  1607.           {
  1608.             SetCurrentOutput(Contents);
  1609.             fprintf(Contents, "\n\\tab\\tab %d.%d.%d\\tab ",
  1610.                                sectionNo, subsectionNo, subsubsectionNo);
  1611.           }
  1612.           else
  1613.             SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
  1614.     }
  1615.         else
  1616.           SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
  1617.       }
  1618.       
  1619.       if (startedSections)
  1620.       {
  1621.         if (winHelp)
  1622.           fprintf(Subsubsections, "\\page\n");
  1623.         else
  1624.           fprintf(Chapters, "\\par\n");
  1625.       }
  1626.  
  1627.       startedSections = TRUE;
  1628.  
  1629.       if (winHelp)
  1630.         fprintf(Subsubsections, "\n${\\footnote ");
  1631.  
  1632.       // Output header to contents page
  1633.       OutputCurrentSection();
  1634.  
  1635.       if (winHelp)
  1636.         fprintf(Subsections, "}{\\v %s}\\par\\pard\n", topicName);
  1637.       else if ((DocumentStyle == LATEX_ARTICLE) && (macroId != ltSUBSUBSECTIONSTAR))
  1638.         fprintf(Contents, "\\par\\pard\n");
  1639.         
  1640.       SetCurrentOutput(winHelp ? Subsubsections : Chapters);
  1641.       if (winHelp)
  1642.       {
  1643.         fprintf(Subsubsections, "}\n#{\\footnote %s}\n", topicName);
  1644.         fprintf(Subsubsections, "+{\\footnote %s}\n", GetBrowseString());
  1645.         OutputSectionKeyword(Subsubsections);
  1646.         GenerateKeywordsForTopic(topicName);
  1647.         if (useUpButton && CurrentSubsectionName)
  1648.         {
  1649.           fprintf(Subsubsections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1650.              FileNameFromPath(FileRoot), CurrentSubsectionName);
  1651.         }
  1652.       }
  1653.       if (!winHelp && indexSubsections && useWord)
  1654.       {
  1655.         // Insert index entry for this subsubsection
  1656.         TexOutput("{\\xe\\v {");
  1657.         OutputCurrentSection();
  1658.         TexOutput("}}");
  1659.       }
  1660.  
  1661.       char *styleCommand = "";
  1662.       if (!winHelp && useHeadingStyles && (macroId != ltSUBSUBSECTIONSTAR))
  1663.       {
  1664.         if (DocumentStyle == LATEX_ARTICLE)
  1665.           styleCommand = "\\s3";
  1666.         else
  1667.           styleCommand = "\\s4";
  1668.       }
  1669.       char *keep = "";
  1670.       if (winHelp)
  1671.         keep = "\\keepn\\sa140\\sb140";
  1672.  
  1673.       fprintf(winHelp ? Subsubsections : Chapters, "\\pard{%s%s",
  1674.          keep, styleCommand);
  1675.  
  1676.       WriteHeadingStyle((winHelp ? Subsubsections : Chapters),
  1677.                         (DocumentStyle == LATEX_ARTICLE ? 3 : 4));
  1678.       fprintf(winHelp ? Subsubsections : Chapters, " ");
  1679.          
  1680.       if (!winHelp)
  1681.       {
  1682.         if ((macroId != ltSUBSUBSECTIONSTAR))
  1683.         {
  1684.           if (DocumentStyle == LATEX_ARTICLE)
  1685.           {
  1686.             if (useWord)
  1687. //              fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. ", topicName, sectionNo, subsectionNo, subsubsectionNo,
  1688.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
  1689.                      topicName);
  1690.             else
  1691.               fprintf(Chapters, "%d.%d.%d. ", sectionNo, subsectionNo, subsubsectionNo);
  1692.           }
  1693.           else
  1694.           {
  1695.             if (useWord)
  1696. //              fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo, subsectionNo, subsubsectionNo,
  1697.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
  1698.                       topicName);
  1699.             else
  1700.               fprintf(Chapters, "%d.%d.%d.%d. ", chapterNo, sectionNo, subsectionNo, subsubsectionNo);
  1701.           }
  1702.         }
  1703.         else if ( useWord )
  1704.         {
  1705.               fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
  1706.         }
  1707.       }
  1708.       OutputCurrentSection(); // Repeat section header
  1709.       TexOutput("\\par\\pard}\\par\n");
  1710.       issuedNewParagraph = 2;
  1711. //      if (winHelp) TexOutput("\\pard");
  1712.     }
  1713.     }
  1714.     break;
  1715.   }
  1716.   case ltCAPTION:
  1717.   case ltCAPTIONSTAR:
  1718.   {
  1719.     if (!start)
  1720.     {
  1721.       char *topicName = FindTopicName(GetNextChunk());
  1722.       SetCurrentTopic(topicName);
  1723.  
  1724.       TexOutput("\\pard\\par");
  1725.       char figBuf[200];
  1726.  
  1727.       if (inFigure)
  1728.       {
  1729.         figureNo ++;
  1730.  
  1731.         if (winHelp || !useWord)
  1732.         {
  1733.           if (DocumentStyle != LATEX_ARTICLE)
  1734.             sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo);
  1735.           else
  1736.             sprintf(figBuf, "%s %d: ", FigureNameString, figureNo);
  1737.         }
  1738.         else
  1739.         {
  1740.           sprintf(figBuf, "%s {\\field\\flddirty{\\*\\fldinst  SEQ Figure \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: ",
  1741.                FigureNameString, topicName, topicName);
  1742.         }
  1743.       }
  1744.       else
  1745.       {
  1746.         tableNo ++;
  1747.  
  1748.         if (winHelp || !useWord)
  1749.         {
  1750.           if (DocumentStyle != LATEX_ARTICLE)
  1751.             sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, tableNo);
  1752.           else
  1753.             sprintf(figBuf, "%s %d: ", TableNameString, tableNo);
  1754.         }
  1755.         else
  1756.         {
  1757.           sprintf(figBuf, "%s {\\field\\flddirty{\\*\\fldinst  SEQ Table \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: ",
  1758.                TableNameString, topicName, topicName);
  1759.         }
  1760.       }
  1761.  
  1762.       int n = (inTable ? tableNo : figureNo);
  1763.       AddTexRef(topicName, NULL, NULL,
  1764.            ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
  1765.             ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
  1766.  
  1767.       if (winHelp)
  1768.         TexOutput("\\qc{\\b ");
  1769.       else
  1770.         TexOutput("\\ql{\\b ");
  1771.       TexOutput(figBuf);
  1772.  
  1773.       OutputCurrentSection();
  1774.  
  1775.       TexOutput("}\\par\\pard\n");
  1776.       WriteEnvironmentStyles();
  1777.     }
  1778.     break;
  1779.   }
  1780.   case ltFUNC:
  1781.   case ltPFUNC:
  1782.   {
  1783. //    SetCurrentOutput(winHelp ? Subsections : Chapters);
  1784.     if (start)
  1785.     {
  1786.       TexOutput("{");
  1787.     }
  1788.     else
  1789.     {
  1790.       TexOutput("}\n");
  1791.       if (winHelp)
  1792.       {
  1793.         TexOutput("K{\\footnote {K} ");
  1794.         suppressNameDecoration = TRUE;
  1795.         TraverseChildrenFromChunk(currentMember);
  1796.         suppressNameDecoration = FALSE;
  1797.         TexOutput("}\n");
  1798.       }
  1799.       if (!winHelp && useWord)
  1800.       {
  1801.         // Insert index entry for this function
  1802.         TexOutput("{\\xe\\v {");
  1803.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1804.         TraverseChildrenFromChunk(currentMember);
  1805.         suppressNameDecoration = FALSE;
  1806.         TexOutput("}}");
  1807.       }
  1808.     }
  1809.     break;
  1810.   }
  1811.   case ltCLIPSFUNC:
  1812.   {
  1813. //    SetCurrentOutput(winHelp ? Subsections : Chapters);
  1814.     if (start)
  1815.     {
  1816.       TexOutput("{");
  1817.     }
  1818.     else
  1819.     {
  1820.       TexOutput("}\n");
  1821.       if (winHelp)
  1822.       {
  1823.         TexOutput("K{\\footnote {K} ");
  1824.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1825.         TraverseChildrenFromChunk(currentMember);
  1826.         suppressNameDecoration = FALSE;
  1827.         TexOutput("}\n");
  1828.       }
  1829.       if (!winHelp && useWord)
  1830.       {
  1831.         // Insert index entry for this function
  1832.         TexOutput("{\\xe\\v {");
  1833.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1834.         TraverseChildrenFromChunk(currentMember);
  1835.         suppressNameDecoration = FALSE;
  1836.         TexOutput("}}");
  1837.       }
  1838.     }
  1839.     break;
  1840.   }
  1841.   case ltMEMBER:
  1842.   {
  1843. //    SetCurrentOutput(winHelp ? Subsections : Chapters);
  1844.     if (start)
  1845.     {
  1846.       TexOutput("{\\b ");
  1847.     }
  1848.     else
  1849.     {
  1850.       TexOutput("}\n");
  1851.       if (winHelp)
  1852.       {
  1853.         TexOutput("K{\\footnote {K} ");
  1854.         TraverseChildrenFromChunk(currentMember);
  1855.         TexOutput("}\n");
  1856.       }
  1857.       if (!winHelp && useWord)
  1858.       {
  1859.         // Insert index entry for this function
  1860.         TexOutput("{\\xe\\v {");
  1861.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1862.         TraverseChildrenFromChunk(currentMember);
  1863.         suppressNameDecoration = FALSE;
  1864.         TexOutput("}}");
  1865.       }
  1866.     }
  1867.     break;
  1868.   }
  1869.   case ltDOCUMENT:
  1870.   {
  1871.     if (start)
  1872.       SetCurrentOutput(Chapters);
  1873.     break;
  1874.   }
  1875.   case ltTABLEOFCONTENTS:
  1876.   {
  1877.     if (start)
  1878.     {
  1879.       if (!winHelp && useWord)
  1880.       {
  1881.         // Insert Word for Windows table of contents
  1882.         TexOutput("\\par\\pard\\pgnrestart\\sect\\titlepg");
  1883.  
  1884.        // In linear RTF, same as chapter headings.
  1885.         sprintf(buf, "{\\b\\fs%d %s}\\par\\par\\pard\n\n", chapterFont*2, ContentsNameString);
  1886.  
  1887.         TexOutput(buf);
  1888.         sprintf(buf, "{\\field{\\*\\fldinst TOC \\\\o \"1-%d\" }{\\fldrslt PRESS F9 TO REFORMAT CONTENTS}}\n", contentsDepth);
  1889.         TexOutput(buf);
  1890. //        TexOutput("\\sect\\sectd");
  1891.       }
  1892.       else
  1893.       {
  1894.         FILE *fd = fopen(ContentsName, "r");
  1895.         if (fd)
  1896.         {
  1897.           int ch = getc(fd);
  1898.           while (ch != EOF)
  1899.           {
  1900.             putc(ch, Chapters);
  1901.             ch = getc(fd);
  1902.           }
  1903.           fclose(fd);
  1904.         }
  1905.         else
  1906.         {
  1907.           TexOutput("{\\i RUN TEX2RTF AGAIN FOR CONTENTS PAGE}\\par\n");
  1908.           OnInform("Run Tex2RTF again to include contents page.");
  1909.         }
  1910.       }
  1911.     }
  1912.     break;
  1913.   }
  1914.   case ltVOID:
  1915.   {
  1916. //    if (start)
  1917. //      TexOutput("{\\b void}");
  1918.     break;
  1919.   }
  1920.   case ltHARDY:
  1921.   {
  1922.     if (start)
  1923.       TexOutput("{\\scaps HARDY}");
  1924.     break;
  1925.   }
  1926.   case ltWXCLIPS:
  1927.   {
  1928.     if (start)
  1929.       TexOutput("wxCLIPS");
  1930.     break;
  1931.   }
  1932.   case ltSPECIALAMPERSAND:
  1933.   {
  1934.     if (start)
  1935.     {
  1936.       if (inTabular)
  1937.         TexOutput("\\cell ");
  1938.       else
  1939.         TexOutput("&");
  1940.     }
  1941.     break;
  1942.   }
  1943.   case ltSPECIALTILDE:
  1944.   {
  1945.     if (start)
  1946.     {
  1947.       if (inVerbatim)
  1948.         TexOutput("~");
  1949.       else
  1950.         TexOutput(" ");
  1951.     }
  1952.     break;
  1953.   }
  1954.   case ltBACKSLASHCHAR:
  1955.   {
  1956.     if (start)
  1957.     {
  1958.       if (inTabular)
  1959.       {
  1960. //        TexOutput("\\cell\\row\\trowd\\trgaph108\\trleft-108\n");
  1961.         TexOutput("\\cell\\row\\trowd\\trgaph108\n");
  1962.         int currentWidth = 0;
  1963.         for (int i = 0; i < noColumns; i++)
  1964.         {
  1965.           currentWidth += TableData[i].width;
  1966.           if (TableData[i].rightBorder)
  1967.             TexOutput("\\clbrdrr\\brdrs\\brdrw15");
  1968.  
  1969.           if (TableData[i].leftBorder)
  1970.             TexOutput("\\clbrdrl\\brdrs\\brdrw15");
  1971.           
  1972.           sprintf(buf, "\\cellx%d", currentWidth);
  1973.           TexOutput(buf);
  1974.         }
  1975.         TexOutput("\\pard\\intbl\n");
  1976.       }
  1977.       else
  1978.         TexOutput("\\line\n");
  1979.     }
  1980.     break;
  1981.   }
  1982.   case ltRANGLEBRA:
  1983.   {
  1984.     if (start)
  1985.       TexOutput("\tab ");
  1986.     break;
  1987.   }
  1988.   case ltRTFSP:  // Explicit space, RTF only
  1989.   {
  1990.     if (start)
  1991.       TexOutput(" ");
  1992.    break;
  1993.   }
  1994.   case ltITEMIZE:
  1995.   case ltENUMERATE:
  1996.   case ltDESCRIPTION:
  1997.   {
  1998.     if (start)
  1999.     {
  2000.       if (indentLevel > 0)
  2001.       {
  2002.         TexOutput("\\par\\par\n");
  2003.         issuedNewParagraph = 2;
  2004.       }
  2005.       else
  2006.       {
  2007.         // Top-level list: issue a new paragraph if we haven't
  2008.         // just done so
  2009.         if (!issuedNewParagraph)
  2010.         {
  2011.           TexOutput("\\par\\pard");
  2012.           WriteEnvironmentStyles();
  2013.           issuedNewParagraph = 1;
  2014.         }
  2015.         else issuedNewParagraph = 0;
  2016.       }
  2017.       indentLevel ++;
  2018.       TexOutput("\\fi0\n");
  2019.       int listType;
  2020.       if (macroId == ltENUMERATE)
  2021.         listType = LATEX_ENUMERATE;
  2022.       else if (macroId == ltITEMIZE)
  2023.         listType = LATEX_ITEMIZE;
  2024.       else
  2025.         listType = LATEX_DESCRIPTION;
  2026.  
  2027.       int oldIndent = 0;
  2028.       wxNode *node = itemizeStack.First();
  2029.       if (node)
  2030.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  2031.  
  2032.       int indentSize1 = oldIndent + 20*labelIndentTab;
  2033.       int indentSize2 = oldIndent + 20*itemIndentTab;
  2034.  
  2035.       ItemizeStruc *struc = new ItemizeStruc(listType, indentSize2, indentSize1);
  2036.       itemizeStack.Insert(struc);
  2037.       
  2038.       sprintf(buf, "\\tx%d\\tx%d\\li%d", indentSize1, indentSize2, indentSize2);
  2039.       PushEnvironmentStyle(buf);
  2040.     }
  2041.     else
  2042.     {
  2043.       currentItemSep = 8; // Reset to the default
  2044.       indentLevel --;
  2045.       PopEnvironmentStyle();
  2046.  
  2047.       if (itemizeStack.First())
  2048.       {
  2049.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  2050.         delete struc;
  2051.         delete itemizeStack.First();
  2052.       }
  2053. /* Change 18/7/97 - don't know why we wish to do this
  2054.       if (itemizeStack.Number() == 0)
  2055.       {
  2056.         OnMacro(ltPAR, 0, TRUE);
  2057.         OnMacro(ltPAR, 0, FALSE);
  2058.         issuedNewParagraph = 2;
  2059.       }
  2060. */
  2061.     }
  2062.     break;
  2063.   }
  2064.   case ltTWOCOLLIST:
  2065.   {
  2066.     if (start)
  2067.     {
  2068.       indentLevel ++;
  2069.       int oldIndent = 0;
  2070.       wxNode *node = itemizeStack.First();
  2071.       if (node)
  2072.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  2073.  
  2074.       int indentSize = oldIndent + TwoColWidthA;
  2075.  
  2076.       ItemizeStruc *struc = new ItemizeStruc(LATEX_TWOCOL, indentSize);
  2077.       itemizeStack.Insert(struc);
  2078.       
  2079. //      sprintf(buf, "\\tx%d\\li%d\\ri%d", indentSize, indentSize, TwoColWidthA+TwoColWidthB+oldIndent);
  2080.       sprintf(buf, "\\tx%d\\li%d", indentSize, indentSize);
  2081.       PushEnvironmentStyle(buf);
  2082.     }
  2083.     else
  2084.     {
  2085.       indentLevel --;
  2086.       PopEnvironmentStyle();
  2087.       if (itemizeStack.First())
  2088.       {
  2089.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  2090.         delete struc;
  2091.         delete itemizeStack.First();
  2092.       }
  2093. /*
  2094.       // JACS June 1997
  2095.       TexOutput("\\pard\n");
  2096.       WriteEnvironmentStyles();
  2097. */
  2098. /* why do we need this? */
  2099.       if (itemizeStack.Number() == 0)
  2100.       {
  2101.         issuedNewParagraph = 0;
  2102.         OnMacro(ltPAR, 0, TRUE);
  2103.         OnMacro(ltPAR, 0, FALSE);
  2104.       }
  2105.     }
  2106.     break;
  2107.   }
  2108.   case ltITEM:
  2109.   {
  2110.     wxNode *node = itemizeStack.First();
  2111.     if (node)
  2112.     {
  2113.       ItemizeStruc *struc = (ItemizeStruc *)node->Data();
  2114.       if (!start)
  2115.       {
  2116.         struc->currentItem += 1;
  2117.         char indentBuf[60];
  2118.  
  2119.         int indentSize1 = struc->labelIndentation;
  2120.         int indentSize2 = struc->indentation;
  2121.  
  2122.         TexOutput("\n");
  2123.         if (struc->currentItem > 1)
  2124.         {
  2125.           if (currentItemSep > 0)
  2126.             TexOutput("\\par");
  2127.  
  2128.           TexOutput("\\par");
  2129. //          WriteEnvironmentStyles();
  2130.         }
  2131.  
  2132.         sprintf(buf, "\\tx%d\\tx%d\\li%d\\fi-%d\n", indentSize1, indentSize2,
  2133.                   indentSize2, 20*itemIndentTab);
  2134.         TexOutput(buf);
  2135.  
  2136.         switch (struc->listType)
  2137.         {
  2138.           case LATEX_ENUMERATE:
  2139.           {
  2140.             if (descriptionItemArg)
  2141.             {
  2142.               TexOutput("\\tab{ ");
  2143.               TraverseChildrenFromChunk(descriptionItemArg);
  2144.               TexOutput("}\\tab");
  2145.               descriptionItemArg = NULL;
  2146.         }
  2147.         else
  2148.         {
  2149.               sprintf(indentBuf, "\\tab{\\b %d.}\\tab", struc->currentItem);
  2150.               TexOutput(indentBuf);
  2151.             }
  2152.             break;
  2153.           }
  2154.           case LATEX_ITEMIZE:
  2155.           {
  2156.             if (descriptionItemArg)
  2157.             {
  2158.               TexOutput("\\tab{ ");
  2159.               TraverseChildrenFromChunk(descriptionItemArg);
  2160.               TexOutput("}\\tab");
  2161.               descriptionItemArg = NULL;
  2162.         }
  2163.         else
  2164.         {
  2165.               if (bulletFile && winHelp)
  2166.               {
  2167.                 if (winHelpVersion > 3) // Transparent bitmap
  2168.                   sprintf(indentBuf, "\\tab\\{bmct %s\\}\\tab", bulletFile);
  2169.                 else
  2170.                   sprintf(indentBuf, "\\tab\\{bmc %s\\}\\tab", bulletFile);
  2171.               }
  2172.               else if (winHelp)
  2173.                 sprintf(indentBuf, "\\tab{\\b o}\\tab");
  2174.               else
  2175.                 sprintf(indentBuf, "\\tab{\\f1\\'b7}\\tab");
  2176.               TexOutput(indentBuf);
  2177.             }
  2178.             break;
  2179.           }
  2180.           default:
  2181.           case LATEX_DESCRIPTION:
  2182.           {
  2183.             if (descriptionItemArg)
  2184.             {
  2185.               TexOutput("\\tab{\\b ");
  2186.               TraverseChildrenFromChunk(descriptionItemArg);
  2187.               TexOutput("}  ");
  2188.               descriptionItemArg = NULL;
  2189.             }
  2190.             break;
  2191.           }
  2192.     }
  2193.       }
  2194.     }
  2195.     break;
  2196.   }
  2197.   case ltTWOCOLITEM:
  2198.   case ltTWOCOLITEMRULED:
  2199.   {
  2200.     wxNode *node = itemizeStack.First();
  2201.     if (node)
  2202.     {
  2203.       ItemizeStruc *struc = (ItemizeStruc *)node->Data();
  2204.       if (start)
  2205.       {
  2206.         struc->currentItem += 1;
  2207.  
  2208.         int oldIndent = 0;
  2209.         wxNode *node2 = NULL;
  2210.         if (itemizeStack.Number() > 1) // TODO: do I actually mean Nth(0) here??
  2211.             node2 = itemizeStack.Nth(1);
  2212.         if (node2)
  2213.           oldIndent = ((ItemizeStruc *)node2->Data())->indentation;
  2214.  
  2215.         TexOutput("\n");
  2216.         if (struc->currentItem > 1)
  2217.         {
  2218.           if (currentItemSep > 0)
  2219.             TexOutput("\\par");
  2220.  
  2221. //          WriteEnvironmentStyles();
  2222.         }
  2223.  
  2224. //        sprintf(buf, "\\tx%d\\li%d\\fi-%d\\ri%d\n", TwoColWidthA,
  2225. //             TwoColWidthA, TwoColWidthA, TwoColWidthA+TwoColWidthB+oldIndent);
  2226. /*
  2227.         sprintf(buf, "\\tx%d\\li%d\\fi-%d\n", TwoColWidthA,
  2228.              TwoColWidthA, TwoColWidthA);
  2229. */
  2230.         sprintf(buf, "\\tx%d\\li%d\\fi-%d\n", TwoColWidthA + oldIndent,
  2231.              TwoColWidthA + oldIndent, TwoColWidthA);
  2232.         TexOutput(buf);
  2233.       }
  2234.     }
  2235.     break;
  2236.   }
  2237.   case ltVERBATIM:
  2238.   case ltVERB:
  2239.   {
  2240.     if (start)
  2241.     {
  2242.       if (macroId == ltVERBATIM)
  2243.       {
  2244.         if (!issuedNewParagraph)
  2245.         {
  2246.           TexOutput("\\par\\pard");
  2247.           WriteEnvironmentStyles();
  2248.           issuedNewParagraph = 1;
  2249.         }
  2250.         else issuedNewParagraph = 0;
  2251.       }
  2252.       sprintf(buf, "{\\f3\\fs20 ");
  2253.       TexOutput(buf);
  2254.     }
  2255.     else
  2256.     {
  2257.       TexOutput("}");
  2258.       if (macroId == ltVERBATIM)
  2259.       {
  2260.         TexOutput("\\pard\n");
  2261. //        issuedNewParagraph = 1;
  2262.         WriteEnvironmentStyles();
  2263.       }
  2264.     }
  2265.     break;
  2266.   }
  2267.   case ltCENTERLINE:
  2268.   case ltCENTER:
  2269.   {
  2270.     if (start)
  2271.     {
  2272.       TexOutput("\\fi0\\qc ");
  2273.       forbidParindent ++;
  2274.       PushEnvironmentStyle("\\qc");
  2275.     }
  2276.     else
  2277.     {
  2278.       TexOutput("\\par\\pard\n");
  2279.       issuedNewParagraph = 1;
  2280.       forbidParindent --;
  2281.       PopEnvironmentStyle();
  2282.       WriteEnvironmentStyles();
  2283.     }
  2284.     break;
  2285.   }
  2286.   case ltFLUSHLEFT:
  2287.   {
  2288.     if (start)
  2289.     {
  2290.       TexOutput("\\fi0\\ql ");
  2291.       forbidParindent ++;
  2292.       PushEnvironmentStyle("\\ql");
  2293.     }
  2294.     else
  2295.     {
  2296.       TexOutput("\\par\\pard\n");
  2297.       issuedNewParagraph = 1;
  2298.       forbidParindent --;
  2299.       PopEnvironmentStyle();
  2300.       WriteEnvironmentStyles();
  2301.     }
  2302.     break;
  2303.   }
  2304.   case ltFLUSHRIGHT:
  2305.   {
  2306.     if (start)
  2307.     {
  2308.       TexOutput("\\fi0\\qr ");
  2309.       forbidParindent ++;
  2310.       PushEnvironmentStyle("\\qr");
  2311.     }
  2312.     else
  2313.     {
  2314.       TexOutput("\\par\\pard\n");
  2315.       issuedNewParagraph = 1;
  2316.       forbidParindent --;
  2317.       PopEnvironmentStyle();
  2318.       WriteEnvironmentStyles();
  2319.     }
  2320.     break;
  2321.   }
  2322.   case ltSMALL:
  2323.   case ltFOOTNOTESIZE:
  2324.   {
  2325.     if (start)
  2326.     {
  2327.       sprintf(buf, "{\\fs%d\n", smallFont*2);
  2328.       TexOutput(buf);
  2329.     }
  2330.     else TexOutput("}\n");
  2331.     break;
  2332.   }
  2333.   case ltTINY:
  2334.   case ltSCRIPTSIZE:
  2335.   {
  2336.     if (start)
  2337.     {
  2338.       sprintf(buf, "{\\fs%d\n", tinyFont*2);
  2339.       TexOutput(buf);
  2340.     }
  2341.     else TexOutput("}\n");
  2342.     break;
  2343.   }
  2344.   case ltNORMALSIZE:
  2345.   {
  2346.     if (start)
  2347.     {
  2348.       sprintf(buf, "{\\fs%d\n", normalFont*2);
  2349.       TexOutput(buf);
  2350.     }
  2351.     else TexOutput("}\n");
  2352.     break;
  2353.   }
  2354.   case ltlarge:
  2355.   {
  2356.     if (start)
  2357.     {
  2358.       sprintf(buf, "{\\fs%d\n", largeFont1*2);
  2359.       TexOutput(buf);
  2360.     }
  2361.     else TexOutput("}\n");
  2362.     break;
  2363.   }
  2364.   case ltLarge:
  2365.   {
  2366.     if (start)
  2367.     {
  2368.       sprintf(buf, "{\\fs%d\n", LargeFont2*2);
  2369.       TexOutput(buf);
  2370.     }
  2371.     else TexOutput("}\n");
  2372.     break;
  2373.   }
  2374.   case ltLARGE:
  2375.   {
  2376.     if (start)
  2377.     {
  2378.       sprintf(buf, "{\\fs%d\n", LARGEFont3*2);
  2379.       TexOutput(buf);
  2380.     }
  2381.     else TexOutput("}\n");
  2382.     break;
  2383.   }
  2384.   case lthuge:
  2385.   {
  2386.     if (start)
  2387.     {
  2388.       sprintf(buf, "{\\fs%d\n", hugeFont1*2);
  2389.       TexOutput(buf);
  2390.     }
  2391.     else TexOutput("}\n");
  2392.     break;
  2393.   }
  2394.   case ltHuge:
  2395.   {
  2396.     if (start)
  2397.     {
  2398.       sprintf(buf, "{\\fs%d\n", HugeFont2*2);
  2399.       TexOutput(buf);
  2400.     }
  2401.     else TexOutput("}\n");
  2402.     break;
  2403.   }
  2404.   case ltHUGE:
  2405.   {
  2406.     if (start)
  2407.     {
  2408.       sprintf(buf, "{\\fs%d\n", HUGEFont3*2);
  2409.       TexOutput(buf);
  2410.     }
  2411.     else TexOutput("}\n");
  2412.     break;
  2413.   }
  2414.   case ltTEXTBF:
  2415.   case ltBFSERIES:
  2416.   case ltBF:
  2417.   {
  2418.     if (start)
  2419.     {
  2420.       TexOutput("{\\b ");
  2421.     }
  2422.     else TexOutput("}");
  2423.     break;
  2424.   }
  2425.   case ltUNDERLINE:
  2426.   {
  2427.     if (start)
  2428.     {
  2429.       TexOutput("{\\ul ");
  2430.     }
  2431.     else TexOutput("}");
  2432.     break;
  2433.   }
  2434.   case ltTEXTIT:
  2435.   case ltITSHAPE:
  2436.   case ltIT:
  2437.   case ltEMPH:
  2438.   case ltEM:
  2439.   {
  2440.     if (start)
  2441.     {
  2442.       TexOutput("{\\i ");
  2443.     }
  2444.     else TexOutput("}");
  2445.     break;
  2446.   }
  2447.   // Roman font: do nothing. Should really switch between
  2448.   // fonts.
  2449.   case ltTEXTRM:
  2450.   case ltRMFAMILY:
  2451.   case ltRM:
  2452.   {
  2453. /*    
  2454.     if (start)
  2455.     {
  2456.       TexOutput("{\\plain ");
  2457.     }
  2458.     else TexOutput("}");
  2459.  */
  2460.     break;
  2461.   }
  2462.   // Medium-weight font. Unbolden...
  2463.   case ltMDSERIES:
  2464.   {
  2465.     if (start)
  2466.     {
  2467.       TexOutput("{\\b0 ");
  2468.     }
  2469.     else TexOutput("}");
  2470.     break;
  2471.   }
  2472.   // Upright (un-italic or slant)
  2473.   case ltUPSHAPE:
  2474.   {
  2475.     if (start)
  2476.     {
  2477.       TexOutput("{\\i0 ");
  2478.     }
  2479.     else TexOutput("}");
  2480.     break;
  2481.   }
  2482.   case ltTEXTSC:
  2483.   case ltSCSHAPE:
  2484.   case ltSC:
  2485.   {
  2486.     if (start)
  2487.     {
  2488.       TexOutput("{\\scaps ");
  2489.     }
  2490.     else TexOutput("}");
  2491.     break;
  2492.   }
  2493.   case ltTEXTTT:
  2494.   case ltTTFAMILY:
  2495.   case ltTT:
  2496.   {
  2497.     if (start)
  2498.     {
  2499.       TexOutput("{\\f3 ");
  2500.     }
  2501.     else TexOutput("}");
  2502.     break;
  2503.   }
  2504.   case ltLBRACE:
  2505.   {
  2506.     if (start)
  2507.       TexOutput("\\{");
  2508.     break;
  2509.   }
  2510.   case ltRBRACE:
  2511.   {
  2512.     if (start)
  2513.       TexOutput("\\}");
  2514.     break;
  2515.   }
  2516.   case ltBACKSLASH:
  2517.   {
  2518.     if (start)
  2519.       TexOutput("\\\\");
  2520.     break;
  2521.   }
  2522.   case ltPAR:
  2523.   {
  2524.     if (start)
  2525.     {
  2526.         if ( issuedNewParagraph == 0 )
  2527.         {
  2528.           TexOutput("\\par\\pard");
  2529.           issuedNewParagraph ++;
  2530.  
  2531.           // Extra par if parskip is more than zero (usually looks best.)
  2532.           if (!inTabular && (ParSkip > 0))
  2533.           {
  2534.             TexOutput("\\par");
  2535.             issuedNewParagraph ++;
  2536.           }
  2537.           WriteEnvironmentStyles();
  2538.         }
  2539.         // 1 is a whole paragraph if ParSkip == 0,
  2540.         // half a paragraph if ParSkip > 0
  2541.         else if ( issuedNewParagraph == 1 )
  2542.         {
  2543.           // Don't need a par at all if we've already had one,
  2544.           // and ParSkip == 0.
  2545.  
  2546.           // Extra par if parskip is more than zero (usually looks best.)
  2547.           if (!inTabular && (ParSkip > 0))
  2548.           {
  2549.             TexOutput("\\par");
  2550.             issuedNewParagraph ++;
  2551.           }
  2552.           WriteEnvironmentStyles();
  2553.         }
  2554. /*
  2555.       if (!issuedNewParagraph || (issuedNewParagraph > 1))
  2556.       {
  2557.         TexOutput("\\par\\pard");
  2558.  
  2559.         // Extra par if parskip is more than zero (usually looks best.)
  2560.         if (!inTabular && (ParSkip > 0))
  2561.           TexOutput("\\par");
  2562.         WriteEnvironmentStyles();
  2563.       }
  2564. */
  2565.  
  2566.       TexOutput("\n");
  2567.     }
  2568.     break;
  2569.   }
  2570.   case ltNEWPAGE:
  2571.   {
  2572.     // In Windows Help, no newpages until we've started some chapters or sections
  2573.     if (!(winHelp && !startedSections))
  2574.       if (start)
  2575.         TexOutput("\\page\n");
  2576.     break;
  2577.   }
  2578.   case ltMAKETITLE:
  2579.   {
  2580.     if (start && DocumentTitle)
  2581.     {
  2582.       TexOutput("\\par\\pard");
  2583.       if (!winHelp)
  2584.         TexOutput("\\par");
  2585.       sprintf(buf, "\\qc{\\fs%d\\b ", titleFont*2);
  2586.       TexOutput(buf);
  2587.       TraverseChildrenFromChunk(DocumentTitle);
  2588.       TexOutput("}\\par\\pard\n");
  2589.  
  2590.       if (DocumentAuthor)
  2591.       {
  2592.         if (!winHelp)
  2593.           TexOutput("\\par");
  2594.         sprintf(buf, "\\par\\qc{\\fs%d ", authorFont*2);
  2595.         TexOutput(buf);
  2596.         TraverseChildrenFromChunk(DocumentAuthor);
  2597.         TexOutput("}");
  2598.         TexOutput("\\par\\pard\n");
  2599.       }
  2600.       if (DocumentDate)
  2601.       {
  2602.         TexOutput("\\par");
  2603.         sprintf(buf, "\\qc{\\fs%d ", authorFont*2);
  2604.         TexOutput(buf);
  2605.         TraverseChildrenFromChunk(DocumentDate);
  2606.         TexOutput("}\\par\\pard\n");
  2607.       }
  2608.       // If linear RTF, we want this titlepage to be in a separate
  2609.       // section with its own (blank) header and footer
  2610.       if (!winHelp && (DocumentStyle != LATEX_ARTICLE))
  2611.       {
  2612.         TexOutput("{\\header }{\\footer }\n");
  2613.         // Not sure about this: we get too many sections.
  2614. //        TexOutput("\\sect");
  2615.       }
  2616.     }
  2617.     break;
  2618.   }
  2619.   case ltADDCONTENTSLINE:
  2620.   {
  2621.     if (!start)
  2622.     {
  2623.     if (contentsLineSection && contentsLineValue)
  2624.     {
  2625.       if (strcmp(contentsLineSection, "chapter") == 0)
  2626.       {
  2627.         fprintf(Contents, "\\par\n{\\b %s}\\par\n", contentsLineValue);
  2628.       }
  2629.       else if (strcmp(contentsLineSection, "section") == 0)
  2630.       {
  2631.         if (DocumentStyle != LATEX_ARTICLE)
  2632.           fprintf(Contents, "\n\\tab%s\\par\n", contentsLineValue);
  2633.         else
  2634.           fprintf(Contents, "\\par\n{\\b %s}\\par\n", contentsLineValue);
  2635.       }
  2636.     }
  2637.     }
  2638.     break;
  2639.   }
  2640.   case ltHRULE:
  2641.   {
  2642.     if (start)
  2643.     {
  2644.       TexOutput("\\brdrb\\brdrs\\par\\pard\n");
  2645.       issuedNewParagraph = 1;
  2646.       WriteEnvironmentStyles();
  2647.     }
  2648.     break;
  2649.   }
  2650.   case ltRULE:
  2651.   {
  2652.     if (start)
  2653.     {
  2654.       TexOutput("\\brdrb\\brdrs\\par\\pard\n");
  2655.       issuedNewParagraph = 1;
  2656.       WriteEnvironmentStyles();
  2657.     }
  2658.     break;
  2659.   }
  2660.   case ltHLINE:
  2661.   {
  2662.     if (start)
  2663.       ruleTop ++;
  2664.     break;
  2665.   }
  2666.   case ltNUMBEREDBIBITEM:
  2667.   {
  2668.     if (start)
  2669.       TexOutput("\\li260\\fi-260 "); // Indent from 2nd line
  2670.     else
  2671.       TexOutput("\\par\\pard\\par\n\n");
  2672.     break;
  2673.   }
  2674.   case ltTHEPAGE:
  2675.   {
  2676.     if (start)
  2677.     {
  2678.       TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  2679.     }
  2680.     break;
  2681.   }
  2682.   case ltTHECHAPTER:
  2683.   {
  2684.     if (start)
  2685.     {
  2686. //      TexOutput("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  2687.       sprintf(buf, "%d", chapterNo);
  2688.       TexOutput(buf);
  2689.     }
  2690.     break;
  2691.   }
  2692.   case ltTHESECTION:
  2693.   {
  2694.     if (start)
  2695.     {
  2696. //      TexOutput("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  2697.       sprintf(buf, "%d", sectionNo);
  2698.       TexOutput(buf);
  2699.     }
  2700.     break;
  2701.   }
  2702.   case ltTWOCOLUMN:
  2703.   {
  2704.     if (!start && !winHelp)
  2705.     {
  2706.       TexOutput("\\cols2\n");
  2707.     }
  2708.     break;
  2709.   }
  2710.   case ltONECOLUMN:
  2711.   {
  2712.     if (!start && !winHelp)
  2713.     {
  2714.       TexOutput("\\cols1\n");
  2715.     }
  2716.     break;
  2717.   }
  2718.   case ltPRINTINDEX:
  2719.   {
  2720.     if (start && useWord && !winHelp)
  2721.     {
  2722.       FakeCurrentSection("Index");
  2723.       OnMacro(ltPAR, 0, TRUE);
  2724.       OnMacro(ltPAR, 0, FALSE);
  2725.       TexOutput("\\par{\\field{\\*\\fldinst INDEX \\\\h \"\\emdash A\\emdash \"\\\\c \"2\"}{\\fldrslt PRESS F9 TO REFORMAT INDEX}}\n");
  2726.     }
  2727.     break;
  2728.   }
  2729.   case ltLISTOFFIGURES:
  2730.   {
  2731.     if (start && useWord && !winHelp)
  2732.     {
  2733.       FakeCurrentSection(FiguresNameString, FALSE);
  2734.       OnMacro(ltPAR, 0, TRUE);
  2735.       OnMacro(ltPAR, 0, FALSE);
  2736.       OnMacro(ltPAR, 0, TRUE);
  2737.       OnMacro(ltPAR, 0, FALSE);
  2738.       char buf[200];
  2739.       sprintf(buf, "{\\field\\fldedit{\\*\\fldinst  TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF FIGURES}}\n",
  2740.                FigureNameString);
  2741.       TexOutput(buf);
  2742.     }
  2743.     break;
  2744.   }
  2745.   case ltLISTOFTABLES:
  2746.   {
  2747.     if (start && useWord && !winHelp)
  2748.     {
  2749.       FakeCurrentSection(TablesNameString, FALSE);
  2750.       OnMacro(ltPAR, 0, TRUE);
  2751.       OnMacro(ltPAR, 0, FALSE);
  2752.       OnMacro(ltPAR, 0, TRUE);
  2753.       OnMacro(ltPAR, 0, FALSE);
  2754.       char buf[200];
  2755.       sprintf(buf, "{\\field\\fldedit{\\*\\fldinst  TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF TABLES}}\n",
  2756.                 TablesNameString);
  2757.       TexOutput(buf);
  2758.     }
  2759.     break;
  2760.   }
  2761.   // Symbols
  2762.   case ltALPHA:
  2763.     if (start) TexOutput("{\\f1\\'61}");
  2764.     break;
  2765.   case ltBETA:
  2766.     if (start) TexOutput("{\\f1\\'62}");
  2767.     break;
  2768.   case ltGAMMA:
  2769.     if (start) TexOutput("{\\f1\\'63}");
  2770.     break;
  2771.   case ltDELTA:
  2772.     if (start) TexOutput("{\\f1\\'64}");
  2773.     break;
  2774.   case ltEPSILON:
  2775.   case ltVAREPSILON:
  2776.     if (start) TexOutput("{\\f1\\'65}");
  2777.     break;
  2778.   case ltZETA:
  2779.     if (start) TexOutput("{\\f1\\'7A}");
  2780.     break;
  2781.   case ltETA:
  2782.     if (start) TexOutput("{\\f1\\'68}");
  2783.     break;
  2784.   case ltTHETA:
  2785.   case ltVARTHETA:
  2786.     if (start) TexOutput("{\\f1\\'71}");
  2787.     break;
  2788.   case ltIOTA:
  2789.     if (start) TexOutput("{\\f1\\'69}");
  2790.     break;
  2791.   case ltKAPPA:
  2792.     if (start) TexOutput("{\\f1\\'6B}");
  2793.     break;
  2794.   case ltLAMBDA:
  2795.     if (start) TexOutput("{\\f1\\'6C}");
  2796.     break;
  2797.   case ltMU:
  2798.     if (start) TexOutput("{\\f1\\'6D}");
  2799.     break;
  2800.   case ltNU:
  2801.     if (start) TexOutput("{\\f1\\'6E}");
  2802.     break;
  2803.   case ltXI:
  2804.     if (start) TexOutput("{\\f1\\'78}");
  2805.     break;
  2806.   case ltPI:
  2807.     if (start) TexOutput("{\\f1\\'70}");
  2808.     break;
  2809.   case ltVARPI:
  2810.     if (start) TexOutput("{\\f1\\'76}");
  2811.     break;
  2812.   case ltRHO:
  2813.   case ltVARRHO:
  2814.     if (start) TexOutput("{\\f1\\'72}");
  2815.     break;
  2816.   case ltSIGMA:
  2817.     if (start) TexOutput("{\\f1\\'73}");
  2818.     break;
  2819.   case ltVARSIGMA:
  2820.     if (start) TexOutput("{\\f1\\'56}");
  2821.     break;
  2822.   case ltTAU:
  2823.     if (start) TexOutput("{\\f1\\'74}");
  2824.     break;
  2825.   case ltUPSILON:
  2826.     if (start) TexOutput("{\\f1\\'75}");
  2827.     break;
  2828.   case ltPHI:
  2829.   case ltVARPHI:
  2830.     if (start) TexOutput("{\\f1\\'66}");
  2831.     break;
  2832.   case ltCHI:
  2833.     if (start) TexOutput("{\\f1\\'63}");
  2834.     break;
  2835.   case ltPSI:
  2836.     if (start) TexOutput("{\\f1\\'79}");
  2837.     break;
  2838.   case ltOMEGA:
  2839.     if (start) TexOutput("{\\f1\\'77}");
  2840.     break;
  2841.   case ltCAP_GAMMA:
  2842.     if (start) TexOutput("{\\f1\\'47}");
  2843.     break;
  2844.   case ltCAP_DELTA:
  2845.     if (start) TexOutput("{\\f1\\'44}");
  2846.     break;
  2847.   case ltCAP_THETA:
  2848.     if (start) TexOutput("{\\f1\\'51}");
  2849.     break;
  2850.   case ltCAP_LAMBDA:
  2851.     if (start) TexOutput("{\\f1\\'4C}");
  2852.     break;
  2853.   case ltCAP_XI:
  2854.     if (start) TexOutput("{\\f1\\'58}");
  2855.     break;
  2856.   case ltCAP_PI:
  2857.     if (start) TexOutput("{\\f1\\'50}");
  2858.     break;
  2859.   case ltCAP_SIGMA:
  2860.     if (start) TexOutput("{\\f1\\'53}");
  2861.     break;
  2862.   case ltCAP_UPSILON:
  2863.     if (start) TexOutput("{\\f1\\'54}");
  2864.     break;
  2865.   case ltCAP_PHI:
  2866.     if (start) TexOutput("{\\f1\\'46}");
  2867.     break;
  2868.   case ltCAP_PSI:
  2869.     if (start) TexOutput("{\\f1\\'59}");
  2870.     break;
  2871.   case ltCAP_OMEGA:
  2872.     if (start) TexOutput("{\\f1\\'57}");
  2873.     break;
  2874.   // Binary operation symbols
  2875.   case ltLE:
  2876.   case ltLEQ:
  2877.     if (start) TexOutput("{\\f1\\'A3}");
  2878.     break;
  2879.   case ltLL:
  2880.     if (start) TexOutput("<<");
  2881.     break;
  2882.   case ltSUBSET:
  2883.     if (start) TexOutput("{\\f1\\'CC}");
  2884.     break;
  2885.   case ltSUBSETEQ:
  2886.     if (start) TexOutput("{\\f1\\'CD}");
  2887.     break;
  2888.   case ltIN:
  2889.     if (start) TexOutput("{\\f1\\'CE}");
  2890.     break;
  2891.   case ltGE:
  2892.   case ltGEQ:
  2893.     if (start) TexOutput("{\\f1\\'B3}");
  2894.     break;
  2895.   case ltGG:
  2896.     if (start) TexOutput(">>");
  2897.     break;
  2898.   case ltSUPSET:
  2899.     if (start) TexOutput("{\\f1\\'C9}");
  2900.     break;
  2901.   case ltSUPSETEQ:
  2902.     if (start) TexOutput("{\\f1\\'CD}");
  2903.     break;
  2904.   case ltNI:
  2905.     if (start) TexOutput("{\\f1\\'27}");
  2906.     break;
  2907.   case ltPERP:
  2908.     if (start) TexOutput("{\\f1\\'5E}");
  2909.     break;
  2910.   case ltNEQ:
  2911.     if (start) TexOutput("{\\f1\\'B9}");
  2912.     break;
  2913.   case ltAPPROX:
  2914.     if (start) TexOutput("{\\f1\\'BB}");
  2915.     break;
  2916.   case ltCONG:
  2917.     if (start) TexOutput("{\\f1\\'40}");
  2918.     break;
  2919.   case ltEQUIV:
  2920.     if (start) TexOutput("{\\f1\\'BA}");
  2921.     break;
  2922.   case ltPROPTO:
  2923.     if (start) TexOutput("{\\f1\\'B5}");
  2924.     break;
  2925.   case ltSIM:
  2926.     if (start) TexOutput("{\\f1\\'7E}");
  2927.     break;
  2928.   case ltSMILE:
  2929.     if (start) TexOutput("{\\f4\\'4A}");
  2930.     break;
  2931.   case ltFROWN:
  2932.     if (start) TexOutput("{\\f4\\'4C}");
  2933.     break;
  2934.   case ltMID:
  2935.     if (start) TexOutput("|");
  2936.     break;
  2937.  
  2938.   // Negated relation symbols
  2939.   case ltNOTEQ:
  2940.     if (start) TexOutput("{\\f1\\'B9}");
  2941.     break;
  2942.   case ltNOTIN:
  2943.     if (start) TexOutput("{\\f1\\'CF}");
  2944.     break;
  2945.   case ltNOTSUBSET:
  2946.     if (start) TexOutput("{\\f1\\'CB}");
  2947.     break;
  2948.  
  2949.   // Arrows
  2950.   case ltLEFTARROW:
  2951.      if (start) TexOutput("{\\f1\\'AC}");
  2952.     break;
  2953.   case ltLEFTARROW2:
  2954.     if (start) TexOutput("{\\f1\\'DC}");
  2955.     break;
  2956.   case ltRIGHTARROW:
  2957.     if (start) TexOutput("{\\f1\\'AE}");
  2958.     break;
  2959.   case ltRIGHTARROW2:
  2960.     if (start) TexOutput("{\\f1\\'DE}");
  2961.     break;
  2962.   case ltLEFTRIGHTARROW:
  2963.     if (start) TexOutput("{\\f1\\'AB}");
  2964.     break;
  2965.   case ltLEFTRIGHTARROW2:
  2966.     if (start) TexOutput("{\\f1\\'DB}");
  2967.     break;
  2968.   case ltUPARROW:
  2969.     if (start) TexOutput("{\\f1\\'AD}");
  2970.     break;
  2971.   case ltUPARROW2:
  2972.     if (start) TexOutput("{\\f1\\'DD}");
  2973.     break;
  2974.   case ltDOWNARROW:
  2975.     if (start) TexOutput("{\\f1\\'AF}");
  2976.     break;
  2977.   case ltDOWNARROW2:
  2978.     if (start) TexOutput("{\\f1\\'DF}");
  2979.     break;
  2980.  
  2981.   // Miscellaneous symbols
  2982.   case ltALEPH:
  2983.     if (start) TexOutput("{\\f1\\'CO}");
  2984.     break;
  2985.   case ltWP:
  2986.     if (start) TexOutput("{\\f1\\'C3}");
  2987.     break;
  2988.   case ltRE:
  2989.     if (start) TexOutput("{\\f1\\'C2}");
  2990.     break;
  2991.   case ltIM:
  2992.     if (start) TexOutput("{\\f1\\'C1}");
  2993.     break;
  2994.   case ltEMPTYSET:
  2995.     if (start) TexOutput("{\\f1\\'C6}");
  2996.     break;
  2997.   case ltNABLA:
  2998.     if (start) TexOutput("{\\f1\\'D1}");
  2999.     break;
  3000.   case ltSURD:
  3001.     if (start) TexOutput("{\\f1\\'D6}");
  3002.     break;
  3003.   case ltPARTIAL:
  3004.     if (start) TexOutput("{\\f1\\'B6}");
  3005.     break;
  3006.   case ltBOT:
  3007.     if (start) TexOutput("{\\f1\\'5E}");
  3008.     break;
  3009.   case ltFORALL:
  3010.     if (start) TexOutput("{\\f1\\'22}");
  3011.     break;
  3012.   case ltEXISTS:
  3013.     if (start) TexOutput("{\\f1\\'24}");
  3014.     break;
  3015.   case ltNEG:
  3016.     if (start) TexOutput("{\\f1\\'D8}");
  3017.     break;
  3018.   case ltSHARP:
  3019.     if (start) TexOutput("{\\f1\\'23}");
  3020.     break;
  3021.   case ltANGLE:
  3022.     if (start) TexOutput("{\\f1\\'D0}");
  3023.     break;
  3024.   case ltTRIANGLE:
  3025.     if (start) TexOutput("{\\f5\\'73}");
  3026.     break;
  3027.   case ltCLUBSUIT:
  3028.     if (start) TexOutput("{\\f5\\'A8}");
  3029.     break;
  3030.   case ltDIAMONDSUIT:
  3031.     if (start) TexOutput("{\\f5\\'A9}");
  3032.     break;
  3033.   case ltHEARTSUIT:
  3034.     if (start) TexOutput("{\\f5\\'AA}");
  3035.     break;
  3036.   case ltSPADESUIT:
  3037.     if (start) TexOutput("{\\f5\\'AB}");
  3038.     break;
  3039.   case ltINFTY:
  3040.     if (start) TexOutput("{\\f1\\'A5}");
  3041.     break;
  3042.   case ltCOPYRIGHT:
  3043.     if (start) TexOutput("{\\f0\\'A9}");
  3044.     break;
  3045.   case ltREGISTERED:
  3046.     if (start) TexOutput("{\\f0\\'AE}");
  3047.     break;
  3048.   case ltPM:
  3049.     if (start) TexOutput("{\\f1\\'B1}");
  3050.     break;
  3051.   case ltMP:
  3052.     if (start) TexOutput("{\\f1\\'B1}");
  3053.     break;
  3054.   case ltTIMES:
  3055.     if (start) TexOutput("{\\f1\\'B4}");
  3056.     break;
  3057.   case ltDIV:
  3058.     if (start) TexOutput("{\\f1\\'B8}");
  3059.     break;
  3060.   case ltCDOT:
  3061.     if (start) TexOutput("{\\f1\\'D7}");
  3062.     break;
  3063.   case ltAST:
  3064.     if (start) TexOutput("{\\f1\\'2A}");
  3065.     break;
  3066.   case ltSTAR:
  3067.     if (start) TexOutput("{\\f5\\'AB}");
  3068.     break;
  3069.   case ltCAP:
  3070.     if (start) TexOutput("{\\f1\\'C7}");
  3071.     break;
  3072.   case ltCUP:
  3073.     if (start) TexOutput("{\\f1\\'C8}");
  3074.     break;
  3075.   case ltVEE:
  3076.     if (start) TexOutput("{\\f1\\'DA}");
  3077.     break;
  3078.   case ltWEDGE:
  3079.     if (start) TexOutput("{\\f1\\'D9}");
  3080.     break;
  3081.   case ltCIRC:
  3082.     if (start) TexOutput("{\\f1\\'B0}");
  3083.     break;
  3084.   case ltBULLET:
  3085.     if (start) TexOutput("{\\f1\\'B7}");
  3086.     break;
  3087.   case ltDIAMOND:
  3088.     if (start) TexOutput("{\\f1\\'E0}");
  3089.     break;
  3090.   case ltBOX:
  3091.     if (start) TexOutput("{\\f1\\'C6}");
  3092.     break;
  3093.   case ltDIAMOND2:
  3094.     if (start) TexOutput("{\\f1\\'E0}");
  3095.     break;
  3096.   case ltBIGTRIANGLEDOWN:
  3097.     if (start) TexOutput("{\\f1\\'D1}");
  3098.     break;
  3099.   case ltOPLUS:
  3100.     if (start) TexOutput("{\\f1\\'C5}");
  3101.     break;
  3102.   case ltOTIMES:
  3103.     if (start) TexOutput("{\\f1\\'C4}");
  3104.     break;
  3105.   case ltSS:
  3106.     if (start) TexOutput("{\\'DF}");
  3107.     break;
  3108.   case ltFIGURE:
  3109.   {
  3110.     if (start) inFigure = TRUE;
  3111.     else inFigure = FALSE;
  3112.     break;
  3113.   }
  3114.   case ltTABLE:
  3115.   {
  3116.     if (start) inTable = TRUE;
  3117.     else inTable = FALSE;
  3118.     break;
  3119.   }
  3120.   default:
  3121.   {
  3122.     DefaultOnMacro(macroId, no_args, start);
  3123.     break;
  3124.   }
  3125.   }
  3126. }
  3127.  
  3128. // Called on start/end of argument examination
  3129. bool RTFOnArgument(int macroId, int arg_no, bool start)
  3130. {
  3131.   char buf[300];
  3132.   switch (macroId)
  3133.   {
  3134.   case ltCHAPTER:
  3135.   case ltCHAPTERSTAR:
  3136.   case ltCHAPTERHEADING:
  3137.   case ltSECTION:
  3138.   case ltSECTIONSTAR:
  3139.   case ltSECTIONHEADING:
  3140.   case ltSUBSECTION:
  3141.   case ltSUBSECTIONSTAR:
  3142.   case ltSUBSUBSECTION:
  3143.   case ltSUBSUBSECTIONSTAR:
  3144.   case ltGLOSS:
  3145.   case ltMEMBERSECTION:
  3146.   case ltFUNCTIONSECTION:
  3147.   case ltCAPTION:
  3148.   case ltCAPTIONSTAR:
  3149.   {
  3150.     if (!start && (arg_no == 1))
  3151.       currentSection = GetArgChunk();
  3152.     return FALSE;
  3153.     break;
  3154.   }
  3155.   case ltFUNC:
  3156.   {
  3157.     if (start && (arg_no == 1))
  3158.       TexOutput("\\pard\\li600\\fi-600{\\b ");
  3159.  
  3160.     if (!start && (arg_no == 1))
  3161.       TexOutput("} ");
  3162.  
  3163.     if (start && (arg_no == 2))
  3164.     {
  3165.       if (!suppressNameDecoration) TexOutput("{\\b ");
  3166.       currentMember = GetArgChunk();
  3167.     }
  3168.     if (!start && (arg_no == 2))
  3169.     {
  3170.       if (!suppressNameDecoration) TexOutput("}");
  3171.     }
  3172.     
  3173.     if (start && (arg_no == 3))
  3174.       TexOutput("(");
  3175.     if (!start && (arg_no == 3))
  3176.     {
  3177. //      TexOutput(")\\li0\\fi0");
  3178. //      TexOutput(")\\par\\pard\\li0\\fi0");
  3179. //      issuedNewParagraph = 1;
  3180.       TexOutput(")");
  3181.       WriteEnvironmentStyles();
  3182.     }
  3183.     break;
  3184.   }
  3185.   case ltCLIPSFUNC:
  3186.   {
  3187.     if (start && (arg_no == 1))
  3188.       TexOutput("\\pard\\li260\\fi-260{\\b ");
  3189.     if (!start && (arg_no == 1))
  3190.       TexOutput("} ");
  3191.  
  3192.     if (start && (arg_no == 2))
  3193.     {
  3194.       if (!suppressNameDecoration) TexOutput("({\\b ");
  3195.       currentMember = GetArgChunk();
  3196.     }
  3197.     if (!start && (arg_no == 2))
  3198.     {
  3199.       if (!suppressNameDecoration) TexOutput("}");
  3200.     }
  3201.  
  3202.     if (!start && (arg_no == 3))
  3203.     {
  3204.       TexOutput(")\\li0\\fi0");
  3205.       WriteEnvironmentStyles();
  3206.     }
  3207.     break;
  3208.   }
  3209.   case ltPFUNC:
  3210.   {
  3211.     if (start && (arg_no == 1))
  3212.       TexOutput("\\pard\\li260\\fi-260");
  3213.  
  3214.     if (!start && (arg_no == 1))
  3215.       TexOutput(" ");
  3216.  
  3217.     if (start && (arg_no == 2))
  3218.       TexOutput("(*");
  3219.     if (!start && (arg_no == 2))
  3220.       TexOutput(")");
  3221.  
  3222.     if (start && (arg_no == 2))
  3223.       currentMember = GetArgChunk();
  3224.  
  3225.     if (start && (arg_no == 3))
  3226.       TexOutput("(");
  3227.     if (!start && (arg_no == 3))
  3228.     {
  3229.       TexOutput(")\\li0\\fi0");
  3230.       WriteEnvironmentStyles();
  3231.     }
  3232.     break;
  3233.   }
  3234.   case ltPARAM:
  3235.   {
  3236.     if (start && (arg_no == 1))
  3237.       TexOutput("{\\b ");
  3238.     if (!start && (arg_no == 1))
  3239.       TexOutput("}");
  3240.     if (start && (arg_no == 2))
  3241.     {
  3242.       TexOutput("{\\i ");
  3243.     }
  3244.     if (!start && (arg_no == 2))
  3245.     {
  3246.       TexOutput("}");
  3247.     }
  3248.     break;
  3249.   }
  3250.   case ltCPARAM:
  3251.   {
  3252.     if (start && (arg_no == 1))
  3253.       TexOutput("{\\b ");
  3254.     if (!start && (arg_no == 1))
  3255.       TexOutput("} ");  // This is the difference from param - one space!
  3256.     if (start && (arg_no == 2))
  3257.     {
  3258.       TexOutput("{\\i ");
  3259.     }
  3260.     if (!start && (arg_no == 2))
  3261.     {
  3262.       TexOutput("}");
  3263.     }
  3264.     break;
  3265.   }
  3266.   case ltMEMBER:
  3267.   {
  3268.     if (!start && (arg_no == 1))
  3269.       TexOutput(" ");
  3270.  
  3271.     if (start && (arg_no == 2))
  3272.       currentMember = GetArgChunk();
  3273.     break;
  3274.   }
  3275.   case ltREF:
  3276.   {
  3277.     if (start)
  3278.     {
  3279.       char *sec = NULL;
  3280.       char *secName = NULL;
  3281.       
  3282.       char *refName = GetArgData();
  3283.       if (winHelp || !useWord)
  3284.       {
  3285.         if (refName)
  3286.         {
  3287.           TexRef *texRef = FindReference(refName);
  3288.           if (texRef)
  3289.           {
  3290.             sec = texRef->sectionNumber;
  3291.             secName = texRef->sectionName;
  3292.           }
  3293.         }
  3294.         if (sec)
  3295.         {
  3296.           TexOutput(sec);
  3297.         }
  3298.       }
  3299.       else
  3300.       {
  3301.         fprintf(Chapters, "{\\field{\\*\\fldinst  REF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}",
  3302.                 refName);
  3303.       }
  3304.       return FALSE;
  3305.     }
  3306.     break;
  3307.   }
  3308.   case ltHELPREF:
  3309.   case ltHELPREFN:
  3310.   {
  3311.     if (winHelp)
  3312.     {
  3313.         if ((GetNoArgs() - arg_no) == 1)
  3314.         {
  3315.           if (start)
  3316.             TexOutput("{\\uldb ");
  3317.           else
  3318.             TexOutput("}");
  3319.         }
  3320.         if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  3321.         {
  3322.           if (start)
  3323.           {
  3324.             TexOutput("{\\v ");
  3325.  
  3326.             // Remove green colour/underlining if specified
  3327.             if (!hotSpotUnderline && !hotSpotColour)
  3328.               TexOutput("%");
  3329.             else if (!hotSpotColour)
  3330.               TexOutput("*");
  3331.           }
  3332.           else TexOutput("}");
  3333.         }
  3334.     }
  3335.     else // If a linear document, must resolve the references ourselves
  3336.     {
  3337.       if ((GetNoArgs() - arg_no) == 1)
  3338.       {
  3339.         // In a linear document we display the anchor text in italic plus
  3340.         // the page number.
  3341.         if (start)
  3342.           TexOutput("{\\i ");
  3343.         else
  3344.           TexOutput("}");
  3345.  
  3346.         if (start)
  3347.           helpRefText = GetArgChunk();
  3348.  
  3349.         return TRUE;
  3350.       }
  3351.       else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  3352.       {
  3353.         if (macroId != ltHELPREFN)
  3354.         {
  3355.           char *refName = GetArgData();
  3356.           TexRef *texRef = NULL;
  3357.           if (refName)
  3358.             texRef = FindReference(refName);
  3359.           if (start)
  3360.           {
  3361.             if (texRef || !ignoreBadRefs)
  3362.               TexOutput(" (");
  3363.             if (refName)
  3364.             {
  3365.                 if (texRef || !ignoreBadRefs)
  3366.                 {
  3367.                   if (useWord)
  3368.                   {
  3369.                       char *s = GetArgData();
  3370.                       TexOutput("p. ");
  3371.                       TexOutput("{\\field{\\*\\fldinst  PAGEREF ");
  3372.                       TexOutput(refName);
  3373.                       TexOutput(" \\\\* MERGEFORMAT }{\\fldrslt ??}}");
  3374.                   }
  3375.                   else
  3376.                   {
  3377.                     // Only print section name if we're not in Word mode,
  3378.                     // so can't do page references
  3379.                     if (texRef)
  3380.                     {
  3381.                       TexOutput(texRef->sectionName) ; TexOutput(" "); TexOutput(texRef->sectionNumber);
  3382.                     }
  3383.                     else
  3384.                     {
  3385.                       if (!ignoreBadRefs)
  3386.                         TexOutput("??");
  3387.                       sprintf(buf, "Warning: unresolved reference '%s'", refName);
  3388.                       OnInform(buf);
  3389.                     }
  3390.                   }
  3391.                 }
  3392.             }
  3393.             else TexOutput("??");
  3394.           }
  3395.           else
  3396.           {
  3397.             if (texRef || !ignoreBadRefs)
  3398.               TexOutput(")");
  3399.           }
  3400.         }
  3401.         return FALSE;
  3402.       }
  3403.     }
  3404.     break;
  3405.   }
  3406.   case ltURLREF:
  3407.   {
  3408.     if (arg_no == 1)
  3409.     {
  3410.       return TRUE;
  3411.     }
  3412.     else if (arg_no == 2)
  3413.     {
  3414.       if (start)
  3415.       {
  3416.         inVerbatim = TRUE;
  3417.         TexOutput(" ({\\f3 ");
  3418.       }
  3419.       else
  3420.       {
  3421.         TexOutput("})");
  3422.         inVerbatim = FALSE;
  3423.       }
  3424.       return TRUE;
  3425.     }
  3426.     break;
  3427.   }
  3428.   case ltPOPREF:
  3429.   {
  3430.     if (winHelp)
  3431.     {
  3432.       if ((GetNoArgs() - arg_no) == 1)
  3433.       {
  3434.         if (start)
  3435.           TexOutput("{\\ul ");
  3436.         else
  3437.           TexOutput("}");
  3438.       }
  3439.       if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  3440.       {
  3441.         if (start)
  3442.         {
  3443.           TexOutput("{\\v ");
  3444.  
  3445.           // Remove green colour/underlining if specified
  3446.           if (!hotSpotUnderline && !hotSpotColour)
  3447.             TexOutput("%");
  3448.           else if (!hotSpotColour)
  3449.             TexOutput("*");
  3450.         }
  3451.         else TexOutput("}");
  3452.       }
  3453.     }
  3454.     else // A linear document...
  3455.     {
  3456.       if ((GetNoArgs() - arg_no) == 1)
  3457.       {
  3458.         // In a linear document we just display the anchor text in italic
  3459.         if (start)
  3460.           TexOutput("{\\i ");
  3461.         else
  3462.           TexOutput("}");
  3463.         return TRUE;
  3464.       }
  3465.       else return FALSE;
  3466.     }
  3467.     break;
  3468.   }
  3469.   case ltADDCONTENTSLINE:
  3470.   {
  3471.     if (start && !winHelp)
  3472.     {
  3473.       if (arg_no == 2)
  3474.         contentsLineSection = copystring(GetArgData());
  3475.       else if (arg_no == 3)
  3476.         contentsLineValue = copystring(GetArgData());
  3477.       return FALSE;
  3478.     }
  3479.     else return FALSE;
  3480.     break;
  3481.   }
  3482.   case ltIMAGE:
  3483.   case ltIMAGEL:
  3484.   case ltIMAGER:
  3485.   case ltIMAGEMAP:
  3486.   case ltPSBOXTO:
  3487.   {
  3488.     if (arg_no == 3)
  3489.       return FALSE;
  3490.       
  3491.     static int imageWidth = 0;
  3492.     static int imageHeight = 0;
  3493.     
  3494.     if (start && (arg_no == 1))
  3495.     {
  3496.       char *imageDimensions = copystring(GetArgData());
  3497.       char buf1[50];
  3498.       strcpy(buf1, imageDimensions);
  3499.       char *tok1 = strtok(buf1, ";:");
  3500.       char *tok2 = strtok(NULL, ";:");
  3501.       // Convert points to TWIPS (1 twip = 1/20th of point)
  3502.       imageWidth = (int)(20*(tok1 ? ParseUnitArgument(tok1) : 0));
  3503.       imageHeight = (int)(20*(tok2 ? ParseUnitArgument(tok2) : 0));
  3504.       if (imageDimensions)  // glt
  3505.           delete [] imageDimensions;
  3506.       return FALSE;
  3507.     }  
  3508.     else if (start && (arg_no == 2 ))
  3509.     {
  3510.       char *filename = copystring(GetArgData());
  3511.       wxString f = "";
  3512.       if ((winHelp || (strcmp(bitmapMethod, "includepicture") == 0)  || (strcmp(bitmapMethod, "import") == 0)) && useWord)
  3513.       {
  3514.         if (f == "") // Try for a .shg (segmented hypergraphics file)
  3515.         {
  3516.           strcpy(buf, filename);
  3517.           StripExtension(buf);
  3518.           strcat(buf, ".shg");
  3519.           f = TexPathList.FindValidPath(buf);
  3520.         }
  3521.         if (f == "") // Try for a .bmp
  3522.         {
  3523.           strcpy(buf, filename);
  3524.           StripExtension(buf);
  3525.           strcat(buf, ".bmp");
  3526.           f = TexPathList.FindValidPath(buf);
  3527.         }
  3528.         if (f == "") // Try for a metafile instead
  3529.         {
  3530.           strcpy(buf, filename);
  3531.           StripExtension(buf);
  3532.           strcat(buf, ".wmf");
  3533.           f = TexPathList.FindValidPath(buf);
  3534.         }
  3535.         if (f != "")
  3536.         {
  3537.           if (winHelp)
  3538.           {
  3539.             if (bitmapTransparency && (winHelpVersion > 3))
  3540.               TexOutput("\\{bmct ");
  3541.             else
  3542.               TexOutput("\\{bmc ");
  3543.             wxString str = wxFileNameFromPath(f);
  3544.             TexOutput((char*) (const char*) str);
  3545.             TexOutput("\\}");
  3546.           }
  3547.           else
  3548.           {
  3549.             // Microsoft Word method
  3550.             if (strcmp(bitmapMethod, "import") == 0)
  3551.               TexOutput("{\\field{\\*\\fldinst IMPORT ");
  3552.             else
  3553.               TexOutput("{\\field{\\*\\fldinst INCLUDEPICTURE ");
  3554.  
  3555.             // Full path appears not to be valid!
  3556.             wxString str = wxFileNameFromPath(f);
  3557.             TexOutput((char*)(const char*) str);
  3558. /*
  3559.             int len = strlen(f);
  3560.             char smallBuf[2]; smallBuf[1] = 0;
  3561.             for (int i = 0; i < len; i++)
  3562.             {
  3563.               smallBuf[0] = f[i];
  3564.               TexOutput(smallBuf);
  3565.               if (smallBuf[0] == '\\')
  3566.                 TexOutput(smallBuf);
  3567.             }
  3568. */
  3569.             TexOutput("}{\\fldrslt PRESS F9 TO FORMAT PICTURE}}");
  3570.           }
  3571.         }
  3572.         else
  3573.         {
  3574.           TexOutput("[No BMP or WMF for image file ");
  3575.           TexOutput(filename);
  3576.           TexOutput("]");
  3577.           sprintf(buf, "Warning: could not find a BMP or WMF equivalent for %s.", filename);
  3578.           OnInform(buf);
  3579.         }
  3580.         if (filename)  // glt
  3581.             delete [] filename;
  3582.       }
  3583.       else // linear RTF
  3584.       {
  3585.           if (f == "") // Try for a .bmp
  3586.           {
  3587.             strcpy(buf, filename);
  3588.             StripExtension(buf);
  3589.             strcat(buf, ".bmp");
  3590.             f = TexPathList.FindValidPath(buf);
  3591.           }
  3592.           if (f != "")
  3593.           {
  3594.             FILE *fd = fopen(f, "rb");
  3595.             if (OutputBitmapHeader(fd, winHelp))
  3596.               OutputBitmapData(fd);
  3597.             else
  3598.             {
  3599.               sprintf(buf, "Could not read bitmap %s.\nMay be in wrong format (needs RGB-encoded Windows BMP).", (const char*) f);
  3600.               OnError(buf);
  3601.             }
  3602.             fclose(fd);
  3603.           }
  3604.           else // Try for a metafile instead
  3605.           {
  3606. #ifdef __WXMSW__
  3607.             strcpy(buf, filename);
  3608.             StripExtension(buf);
  3609.             strcat(buf, ".wmf");
  3610.             f = TexPathList.FindValidPath(buf);
  3611.             if (f != "")
  3612.             {
  3613.   //            HFILE handle = _lopen(f, READ);
  3614.               FILE *fd = fopen(f, "rb");
  3615.               if (OutputMetafileHeader(fd, winHelp, imageWidth, imageHeight))
  3616.               {
  3617.                 OutputMetafileData(fd);
  3618.               }
  3619.               else
  3620.               {
  3621.                 sprintf(buf, "Could not read metafile %s. Perhaps it's not a placeable metafile?", f);
  3622.                 OnError(buf);
  3623.               }
  3624.               fclose(fd);
  3625.             }
  3626.             else
  3627.             {
  3628. #endif            
  3629.               TexOutput("[No BMP or WMF for image file ");
  3630.               TexOutput(filename);
  3631.               TexOutput("]");
  3632.               sprintf(buf, "Warning: could not find a BMP or WMF equivalent for %s.", filename);
  3633.               OnInform(buf);
  3634. #ifdef __WXMSW__
  3635.             }
  3636. #endif
  3637.         }
  3638.       }
  3639.       return FALSE;
  3640.     }
  3641.     else
  3642.       return FALSE;
  3643.     break;
  3644.   }
  3645.   case ltTABULAR:
  3646.   case ltSUPERTABULAR:
  3647.   {
  3648.     if (arg_no == 1)
  3649.     {
  3650.       if (start)
  3651.       {
  3652.         currentRowNumber = 0;
  3653.         inTabular = TRUE;
  3654.         startRows = TRUE;
  3655.         tableVerticalLineLeft = FALSE;
  3656.         tableVerticalLineRight = FALSE;
  3657.         int currentWidth = 0;
  3658.  
  3659.         char *alignString = copystring(GetArgData());
  3660.         ParseTableArgument(alignString);
  3661.  
  3662. //        TexOutput("\\trowd\\trgaph108\\trleft-108");
  3663.         TexOutput("\\trowd\\trgaph108");
  3664.  
  3665.         // Write the first row formatting for compatibility
  3666.         // with standard Latex
  3667.         if (compatibilityMode)
  3668.         {
  3669.           for (int i = 0; i < noColumns; i++)
  3670.           {
  3671.             currentWidth += TableData[i].width;
  3672.             sprintf(buf, "\\cellx%d", currentWidth);
  3673.             TexOutput(buf);
  3674.           }
  3675.           TexOutput("\\pard\\intbl\n");
  3676.         }
  3677.         delete[] alignString;
  3678.  
  3679.         return FALSE;
  3680.       }
  3681.     }
  3682.     else if (arg_no == 2 && !start)
  3683.     {
  3684.       TexOutput("\\pard\n");
  3685.       WriteEnvironmentStyles();
  3686.       inTabular = FALSE;
  3687.     }
  3688.     break;
  3689.   }
  3690.  
  3691.   case ltQUOTE:
  3692.   case ltVERSE:
  3693.   {
  3694.     if (start)
  3695.     {
  3696.       TexOutput("\\li360\n");
  3697.       forbidParindent ++;
  3698.       PushEnvironmentStyle("\\li360");
  3699.     }
  3700.     else
  3701.     {
  3702.       forbidParindent --;
  3703.       PopEnvironmentStyle();
  3704.       OnMacro(ltPAR, 0, TRUE);
  3705.       OnMacro(ltPAR, 0, FALSE);
  3706.     }
  3707.     break;
  3708.   }
  3709.   case ltQUOTATION:
  3710.   {
  3711.     if (start)
  3712.     {
  3713.       TexOutput("\\li360\n");
  3714.       PushEnvironmentStyle("\\li360");
  3715.     }
  3716.     else
  3717.     {
  3718.       PopEnvironmentStyle();
  3719.       OnMacro(ltPAR, 0, TRUE);
  3720.       OnMacro(ltPAR, 0, FALSE);
  3721.     }
  3722.     break;
  3723.   }
  3724.   case ltBOXIT:
  3725.   case ltFRAMEBOX:
  3726.   case ltFBOX:
  3727.   case ltNORMALBOX:
  3728.   case ltNORMALBOXD:
  3729.   {
  3730.     if (start)
  3731.     {
  3732.       sprintf(buf, "\\box\\trgaph108%s\n", ((macroId == ltNORMALBOXD) ? "\\brdrdb" : "\\brdrs"));
  3733.       TexOutput(buf);
  3734.       PushEnvironmentStyle(buf);
  3735.     }
  3736.     else
  3737.     {
  3738.       PopEnvironmentStyle();
  3739.       OnMacro(ltPAR, 0, TRUE);
  3740.       OnMacro(ltPAR, 0, FALSE);
  3741.     }
  3742.     break;
  3743.   }
  3744.   case ltHELPFONTSIZE:
  3745.   {
  3746.     if (start)
  3747.     {
  3748.       char *data = GetArgData();
  3749.       if (strcmp(data, "10") == 0)
  3750.         SetFontSizes(10);
  3751.       else if (strcmp(data, "11") == 0)
  3752.         SetFontSizes(11);
  3753.       else if (strcmp(data, "12") == 0)
  3754.         SetFontSizes(12);
  3755.       sprintf(buf, "\\fs%d\n", normalFont*2);
  3756.       TexOutput(buf);
  3757.       TexOutput(buf);
  3758.       return FALSE;
  3759.     }
  3760.     break;
  3761.   }
  3762.   case ltHELPFONTFAMILY:
  3763.   {
  3764.     if (start)
  3765.     {
  3766.       char *data = GetArgData();
  3767.       if (strcmp(data, "Swiss") == 0)
  3768.         TexOutput("\\f2\n");
  3769.       else if (strcmp(data, "Symbol") == 0)
  3770.         TexOutput("\\f1\n");
  3771.       else if (strcmp(data, "Times") == 0)
  3772.         TexOutput("\\f0\n");
  3773.  
  3774.       return FALSE;
  3775.     }
  3776.     break;
  3777.   }
  3778.   case ltPARINDENT:
  3779.   {
  3780.     if (start && arg_no == 1)
  3781.     {
  3782.       char *data = GetArgData();
  3783.       ParIndent = ParseUnitArgument(data);
  3784.       if (ParIndent == 0 || forbidParindent == 0)
  3785.       {
  3786.         sprintf(buf, "\\fi%d\n", ParIndent*20);
  3787.         TexOutput(buf);
  3788.       }
  3789.       return FALSE;
  3790.     }
  3791.     break;
  3792.   }
  3793.   case ltITEM:
  3794.   {
  3795.     if (start && IsArgOptional())
  3796.     {
  3797.       descriptionItemArg = GetArgChunk();
  3798.       return FALSE;
  3799.     }
  3800.     break;
  3801.   }
  3802.   case ltTWOCOLITEM:
  3803.   case ltTWOCOLITEMRULED:
  3804.   {
  3805.     switch (arg_no)
  3806.     {
  3807.       case 1:
  3808.       {
  3809.         if (!start)
  3810.           TexOutput("\\tab ");
  3811.         break;
  3812.       }
  3813.       case 2:
  3814.       {
  3815.         if (!start)
  3816.         {
  3817.           if (macroId == ltTWOCOLITEMRULED)
  3818.             TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  3819.           TexOutput("\\par\\pard\n");
  3820.           issuedNewParagraph = 1;
  3821.           WriteEnvironmentStyles();
  3822.         }
  3823.         break;
  3824.       }
  3825.     }
  3826.     return TRUE;
  3827.     break;
  3828.   }
  3829.   /*
  3830.    * Accents
  3831.    *
  3832.    */
  3833.   case ltACCENT_GRAVE:
  3834.   {
  3835.     if (start)
  3836.     {
  3837.       char *val = GetArgData();
  3838.       if (val)
  3839.       {
  3840.         switch (val[0])
  3841.         {
  3842.           case 'a':
  3843.            TexOutput("\\'e0");
  3844.            break;
  3845.           case 'e':
  3846.            TexOutput("\\'e8");
  3847.            break;
  3848.           case 'i':
  3849.            TexOutput("\\'ec");
  3850.            break;
  3851.           case 'o':
  3852.            TexOutput("\\'f2");
  3853.            break;
  3854.           case 'u':
  3855.            TexOutput("\\'f9");
  3856.            break;
  3857.           case 'A':
  3858.            TexOutput("\\'c0");
  3859.            break;
  3860.           case 'E':
  3861.            TexOutput("\\'c8");
  3862.            break;
  3863.           case 'I':
  3864.            TexOutput("\\'cc");
  3865.            break;
  3866.           case 'O':
  3867.            TexOutput("\\'d2");
  3868.            break;
  3869.           case 'U':
  3870.            TexOutput("\\'d9");
  3871.            break;
  3872.           default:
  3873.            break;
  3874.         }
  3875.       }
  3876.     }
  3877.     return FALSE;
  3878.     break;
  3879.   }
  3880.   case ltACCENT_ACUTE:
  3881.   {
  3882.     if (start)
  3883.     {
  3884.       char *val = GetArgData();
  3885.       if (val)
  3886.       {
  3887.         switch (val[0])
  3888.         {
  3889.           case 'a':
  3890.            TexOutput("\\'e1");
  3891.            break;
  3892.           case 'e':
  3893.            TexOutput("\\'e9");
  3894.            break;
  3895.           case 'i':
  3896.            TexOutput("\\'ed");
  3897.            break;
  3898.           case 'o':
  3899.            TexOutput("\\'f3");
  3900.            break;
  3901.           case 'u':
  3902.            TexOutput("\\'fa");
  3903.            break;
  3904.           case 'y':
  3905.            TexOutput("\\'fd");
  3906.            break;
  3907.           case 'A':
  3908.            TexOutput("\\'c1");
  3909.            break;
  3910.           case 'E':
  3911.            TexOutput("\\'c9");
  3912.            break;
  3913.           case 'I':
  3914.            TexOutput("\\'cd");
  3915.            break;
  3916.           case 'O':
  3917.            TexOutput("\\'d3");
  3918.            break;
  3919.           case 'U':
  3920.            TexOutput("\\'da");
  3921.            break;
  3922.           case 'Y':
  3923.            TexOutput("\\'dd");
  3924.            break;
  3925.           default:
  3926.            break;
  3927.         }
  3928.       }
  3929.     }
  3930.     return FALSE;
  3931.     break;
  3932.   }
  3933.   case ltACCENT_CARET:
  3934.   {
  3935.     if (start)
  3936.     {
  3937.       char *val = GetArgData();
  3938.       if (val)
  3939.       {
  3940.         switch (val[0])
  3941.         {
  3942.           case 'a':
  3943.            TexOutput("\\'e2");
  3944.            break;
  3945.           case 'e':
  3946.            TexOutput("\\'ea");
  3947.            break;
  3948.           case 'i':
  3949.            TexOutput("\\'ee");
  3950.            break;
  3951.           case 'o':
  3952.            TexOutput("\\'f4");
  3953.            break;
  3954.           case 'u':
  3955.            TexOutput("\\'fb");
  3956.            break;
  3957.           case 'A':
  3958.            TexOutput("\\'c2");
  3959.            break;
  3960.           case 'E':
  3961.            TexOutput("\\'ca");
  3962.            break;
  3963.           case 'I':
  3964.            TexOutput("\\'ce");
  3965.            break;
  3966.           case 'O':
  3967.            TexOutput("\\'d4");
  3968.            break;
  3969.           case 'U':
  3970.            TexOutput("\\'db");
  3971.            break;
  3972.           default:
  3973.            break;
  3974.         }
  3975.       }
  3976.     }
  3977.     return FALSE;
  3978.     break;
  3979.   }
  3980.   case ltACCENT_TILDE:
  3981.   {
  3982.     if (start)
  3983.     {
  3984.       char *val = GetArgData();
  3985.       if (val)
  3986.       {
  3987.         switch (val[0])
  3988.         {
  3989.           case 'a':
  3990.            TexOutput("\\'e3");
  3991.            break;
  3992.           case ' ':
  3993.            TexOutput("~");
  3994.            break;
  3995.           case 'n':
  3996.            TexOutput("\\'f1");
  3997.            break;
  3998.           case 'o':
  3999.            TexOutput("\\'f5");
  4000.            break;
  4001.           case 'A':
  4002.            TexOutput("\\'c3");
  4003.            break;
  4004.           case 'N':
  4005.            TexOutput("\\'d1");
  4006.            break;
  4007.           case 'O':
  4008.            TexOutput("\\'d5");
  4009.            break;
  4010.           default:
  4011.            break;
  4012.         }
  4013.       }
  4014.     }
  4015.     return FALSE;
  4016.     break;
  4017.   }
  4018.   case ltACCENT_UMLAUT:
  4019.   {
  4020.     if (start)
  4021.     {
  4022.       char *val = GetArgData();
  4023.       if (val)
  4024.       {
  4025.         switch (val[0])
  4026.         {
  4027.           case 'a':
  4028.            TexOutput("\\'e4");
  4029.            break;
  4030.           case 'e':
  4031.            TexOutput("\\'eb");
  4032.            break;
  4033.           case 'i':
  4034.            TexOutput("\\'ef");
  4035.            break;
  4036.           case 'o':
  4037.            TexOutput("\\'f6");
  4038.            break;
  4039.           case 'u':
  4040.            TexOutput("\\'fc");
  4041.            break;
  4042.           case 's':
  4043.            TexOutput("\\'df");
  4044.            break;
  4045.           case 'y':
  4046.            TexOutput("\\'ff");
  4047.            break;
  4048.           case 'A':
  4049.            TexOutput("\\'c4");
  4050.            break;
  4051.           case 'E':
  4052.            TexOutput("\\'cb");
  4053.            break;
  4054.           case 'I':
  4055.            TexOutput("\\'cf");
  4056.            break;
  4057.           case 'O':
  4058.            TexOutput("\\'d6");
  4059.            break;
  4060.           case 'U':
  4061.            TexOutput("\\'dc");
  4062.            break;
  4063.           case 'Y':
  4064.            TexOutput("\\'df");
  4065.            break;
  4066.           default:
  4067.            break;
  4068.         }
  4069.       }
  4070.     }
  4071.     return FALSE;
  4072.     break;
  4073.   }
  4074.   case ltACCENT_DOT:
  4075.   {
  4076.     if (start)
  4077.     {
  4078.       char *val = GetArgData();
  4079.       if (val)
  4080.       {
  4081.         switch (val[0])
  4082.         {
  4083.           case 'a':
  4084.            TexOutput("\\'e5");
  4085.            break;
  4086.           case 'A':
  4087.            TexOutput("\\'c5");
  4088.            break;
  4089.           default:
  4090.            break;
  4091.         }
  4092.       }
  4093.     }
  4094.     return FALSE;
  4095.     break;
  4096.   }
  4097.   case ltACCENT_CADILLA:
  4098.   {
  4099.     if (start)
  4100.     {
  4101.       char *val = GetArgData();
  4102.       if (val)
  4103.       {
  4104.         switch (val[0])
  4105.         {
  4106.           case 'c':
  4107.            TexOutput("\\'e7");
  4108.            break;
  4109.           case 'C':
  4110.            TexOutput("\\'c7");
  4111.            break;
  4112.           default:
  4113.            break;
  4114.         }
  4115.       }
  4116.     }
  4117.     return FALSE;
  4118.     break;
  4119.   }
  4120.   case ltFOOTNOTE:
  4121.   {
  4122.     static char *helpTopic = NULL;
  4123.     static FILE *savedOutput = NULL;
  4124.     if (winHelp)
  4125.     {
  4126.       if (arg_no == 1)
  4127.       {
  4128.         if (start)
  4129.         {
  4130.           OnInform("Consider using \\footnotepopup instead of \\footnote.");
  4131.           footnoteCount ++;
  4132.           char footBuf[20];
  4133.           sprintf(footBuf, "(%d)", footnoteCount);
  4134.  
  4135.           TexOutput(" {\\ul ");
  4136.           TexOutput(footBuf);
  4137.           TexOutput("}");
  4138.           helpTopic = FindTopicName(NULL);
  4139.           TexOutput("{\\v ");
  4140.  
  4141.           // Remove green colour/underlining if specified
  4142.           if (!hotSpotUnderline && !hotSpotColour)
  4143.             TexOutput("%");
  4144.           else if (!hotSpotColour)
  4145.             TexOutput("*");
  4146.  
  4147.           TexOutput(helpTopic);
  4148.           TexOutput("}");
  4149.  
  4150.           fprintf(Popups, "\\page\n");
  4151. //          fprintf(Popups, "\n${\\footnote }"); // No title
  4152.           fprintf(Popups, "\n#{\\footnote %s}\n", helpTopic);
  4153.           fprintf(Popups, "+{\\footnote %s}\n", GetBrowseString());
  4154.           savedOutput = CurrentOutput1;
  4155.           SetCurrentOutput(Popups);
  4156.     }
  4157.     else
  4158.     {
  4159.           SetCurrentOutput(savedOutput);
  4160.     }
  4161.     return TRUE;
  4162.       }
  4163.       return TRUE;
  4164.     }
  4165.     else
  4166.     {
  4167.       if (start)
  4168.       {
  4169.         TexOutput(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}", TRUE);
  4170.       }
  4171.       else
  4172.       {
  4173.         TexOutput("}}", TRUE);
  4174.       }
  4175.       return TRUE;
  4176.     }
  4177.     break;
  4178.   }
  4179.   case ltFOOTNOTEPOPUP:
  4180.   {
  4181.     static char *helpTopic = NULL;
  4182.     static FILE *savedOutput = NULL;
  4183.     if (winHelp)
  4184.     {
  4185.       if (arg_no == 1)
  4186.       {
  4187.         if (start)
  4188.         {
  4189.           TexOutput("{\\ul ");
  4190.     }
  4191.     else TexOutput("}");
  4192.     return TRUE;
  4193.       }
  4194.       else if (arg_no == 2)
  4195.       {
  4196.         if (start)
  4197.         {
  4198.           helpTopic = FindTopicName(NULL);
  4199.           TexOutput("{\\v ");
  4200.  
  4201.           // Remove green colour/underlining if specified
  4202.           if (!hotSpotUnderline && !hotSpotColour)
  4203.             TexOutput("%");
  4204.           else if (!hotSpotColour)
  4205.             TexOutput("*");
  4206.  
  4207.           TexOutput(helpTopic);
  4208.           TexOutput("}");
  4209.  
  4210.           fprintf(Popups, "\\page\n");
  4211. //          fprintf(Popups, "\n${\\footnote }"); // No title
  4212.           fprintf(Popups, "\n#{\\footnote %s}\n", helpTopic);
  4213.           fprintf(Popups, "+{\\footnote %s}\n", GetBrowseString());
  4214.           savedOutput = CurrentOutput1;
  4215.           SetCurrentOutput(Popups);
  4216.         }
  4217.         else
  4218.         {
  4219.           SetCurrentOutput(savedOutput);
  4220.         }
  4221.         return TRUE;
  4222.       }
  4223.     }
  4224.     else
  4225.     {
  4226.       if (arg_no == 1)
  4227.         return TRUE;
  4228.       if (start)
  4229.       {
  4230.         TexOutput(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}", TRUE);
  4231.       }
  4232.       else
  4233.       {
  4234.         TexOutput("}}", TRUE);
  4235.       }
  4236.       return TRUE;
  4237.     }
  4238.     break;
  4239.   }
  4240.   case ltFANCYPLAIN:
  4241.   {
  4242.     if (start && (arg_no == 1))
  4243.       return FALSE;
  4244.     else
  4245.       return TRUE;
  4246.     break;
  4247.   }
  4248.   case ltSETHEADER:
  4249.   {
  4250.     if (start)
  4251.       forbidResetPar ++;
  4252.     else
  4253.       forbidResetPar --;
  4254.  
  4255.     if (winHelp) return FALSE;
  4256.     if (start)
  4257.     {
  4258.       switch (arg_no)
  4259.       {
  4260.         case 1:
  4261.           LeftHeaderEven = GetArgChunk();
  4262.           if (strlen(GetArgData(LeftHeaderEven)) == 0)
  4263.             LeftHeaderEven = NULL;
  4264.           break;
  4265.         case 2:
  4266.           CentreHeaderEven = GetArgChunk();
  4267.           if (strlen(GetArgData(CentreHeaderEven)) == 0)
  4268.             CentreHeaderEven = NULL;
  4269.           break;
  4270.         case 3:
  4271.           RightHeaderEven = GetArgChunk();
  4272.           if (strlen(GetArgData(RightHeaderEven)) == 0)
  4273.             RightHeaderEven = NULL;
  4274.           break;
  4275.         case 4:
  4276.           LeftHeaderOdd = GetArgChunk();
  4277.           if (strlen(GetArgData(LeftHeaderOdd)) == 0)
  4278.             LeftHeaderOdd = NULL;
  4279.           break;
  4280.         case 5:
  4281.           CentreHeaderOdd = GetArgChunk();
  4282.           if (strlen(GetArgData(CentreHeaderOdd)) == 0)
  4283.             CentreHeaderOdd = NULL;
  4284.           break;
  4285.         case 6:
  4286.           RightHeaderOdd = GetArgChunk();
  4287.           if (strlen(GetArgData(RightHeaderOdd)) == 0)
  4288.             RightHeaderOdd = NULL;
  4289.           OutputRTFHeaderCommands();
  4290.           break;
  4291.         default:
  4292.           break;
  4293.       }
  4294.     }
  4295.     return FALSE;
  4296.     break;
  4297.   }
  4298.   case ltSETFOOTER:
  4299.   {
  4300.     if (start)
  4301.       forbidResetPar ++;
  4302.     else
  4303.       forbidResetPar --;
  4304.  
  4305.     if (winHelp) return FALSE;
  4306.     if (start)
  4307.     {
  4308.       switch (arg_no)
  4309.       {
  4310.         case 1:
  4311.           LeftFooterEven = GetArgChunk();
  4312.           if (strlen(GetArgData(LeftFooterEven)) == 0)
  4313.             LeftFooterEven = NULL;
  4314.           break;
  4315.         case 2:
  4316.           CentreFooterEven = GetArgChunk();
  4317.           if (strlen(GetArgData(CentreFooterEven)) == 0)
  4318.             CentreFooterEven = NULL;
  4319.           break;
  4320.         case 3:
  4321.           RightFooterEven = GetArgChunk();
  4322.           if (strlen(GetArgData(RightFooterEven)) == 0)
  4323.             RightFooterEven = NULL;
  4324.           break;
  4325.         case 4:
  4326.           LeftFooterOdd = GetArgChunk();
  4327.           if (strlen(GetArgData(LeftFooterOdd)) == 0)
  4328.             LeftFooterOdd = NULL;
  4329.           break;
  4330.         case 5:
  4331.           CentreFooterOdd = GetArgChunk();
  4332.           if (strlen(GetArgData(CentreFooterOdd)) == 0)
  4333.             CentreFooterOdd = NULL;
  4334.           break;
  4335.         case 6:
  4336.           RightFooterOdd = GetArgChunk();
  4337.           if (strlen(GetArgData(RightFooterOdd)) == 0)
  4338.             RightFooterOdd = NULL;
  4339.           OutputRTFFooterCommands();
  4340.           break;
  4341.         default:
  4342.           break;
  4343.       }
  4344.     }
  4345.     return FALSE;
  4346.     break;
  4347.   }
  4348.   case ltMARKRIGHT:
  4349.   {
  4350.     if (winHelp) return FALSE;
  4351.     // Fake a SetHeader command
  4352.     if (start)
  4353.     {
  4354.       LeftHeaderOdd = NULL;
  4355.       CentreHeaderOdd = NULL;
  4356.       RightHeaderOdd = NULL;
  4357.       LeftHeaderEven = NULL;
  4358.       CentreHeaderEven = NULL;
  4359.       RightHeaderEven = NULL;
  4360.       OnInform("Consider using setheader/setfooter rather than markright.");
  4361.     }
  4362.     RTFOnArgument(ltSETHEADER, 4, start);
  4363.     if (!start)
  4364.       OutputRTFHeaderCommands();
  4365.     return FALSE;
  4366.     break;
  4367.   }
  4368.   case ltMARKBOTH:
  4369.   {
  4370.     if (winHelp) return FALSE;
  4371.     // Fake a SetHeader command
  4372.     switch (arg_no)
  4373.     {
  4374.       case 1:
  4375.       {
  4376.         if (start)
  4377.         {
  4378.           LeftHeaderOdd = NULL;
  4379.           CentreHeaderOdd = NULL;
  4380.           RightHeaderOdd = NULL;
  4381.           LeftHeaderEven = NULL;
  4382.           CentreHeaderEven = NULL;
  4383.           RightHeaderEven = NULL;
  4384.           OnInform("Consider using setheader/setfooter rather than markboth.");
  4385.         }
  4386.         return RTFOnArgument(ltSETHEADER, 1, start);
  4387.         break;
  4388.       }
  4389.       case 2:
  4390.       {
  4391.         RTFOnArgument(ltSETHEADER, 4, start);
  4392.         if (!start)
  4393.           OutputRTFHeaderCommands();
  4394.         return FALSE;
  4395.         break;
  4396.       }
  4397.     }
  4398.     break;
  4399.   }
  4400.   case ltPAGENUMBERING:
  4401.   {
  4402.     if (start)
  4403.       forbidResetPar ++;
  4404.     else
  4405.       forbidResetPar --;
  4406.  
  4407.     if (winHelp) return FALSE;
  4408.     if (start)
  4409.     {
  4410.       TexOutput("\\pgnrestart");
  4411.       char *data = GetArgData();
  4412.       if (currentNumberStyle) delete[] currentNumberStyle;
  4413.       currentNumberStyle = copystring(data);
  4414.       OutputNumberStyle(currentNumberStyle);
  4415.       
  4416.       TexOutput("\n");
  4417.     }
  4418.     return FALSE;
  4419.     break;
  4420.   }
  4421.   case ltTWOCOLUMN:
  4422.   {
  4423.     if (winHelp) return FALSE;
  4424.     if (start)
  4425.       return TRUE;
  4426.     break;
  4427.   }
  4428.   case ltITEMSEP:
  4429.   {
  4430.     if (start)
  4431.     {
  4432.       char *val = GetArgData();
  4433.       currentItemSep = ParseUnitArgument(val);
  4434.       return FALSE;
  4435.     }
  4436.     break;
  4437.   }
  4438.   case ltEVENSIDEMARGIN:
  4439.   {
  4440.     return FALSE;
  4441.     break;
  4442.   }
  4443.   case ltODDSIDEMARGIN:
  4444.   {
  4445.     if (start)
  4446.     {
  4447.       char *val = GetArgData();
  4448.       int twips = (int)(20*ParseUnitArgument(val));
  4449.       // Add an inch since in LaTeX it's specified minus an inch
  4450.       twips += 1440;
  4451.       CurrentLeftMarginOdd = twips;
  4452.       sprintf(buf, "\\margl%d\n", twips);
  4453.       TexOutput(buf);
  4454.  
  4455.       CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  4456.     }
  4457.     return FALSE;
  4458.   }
  4459.   case ltMARGINPARWIDTH:
  4460.   {
  4461.     if (start)
  4462.     {
  4463.       char *val = GetArgData();
  4464.       int twips = (int)(20*ParseUnitArgument(val));
  4465.       CurrentMarginParWidth = twips;
  4466.     }
  4467.     return FALSE;
  4468.   }
  4469.   case ltMARGINPARSEP:
  4470.   {
  4471.     if (start)
  4472.     {
  4473.       char *val = GetArgData();
  4474.       int twips = (int)(20*ParseUnitArgument(val));
  4475.       CurrentMarginParSep = twips;
  4476.       CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  4477.     }
  4478.     return FALSE;
  4479.   }
  4480.   case ltTEXTWIDTH:
  4481.   {
  4482.     if (start)
  4483.     {
  4484.       char *val = GetArgData();
  4485.       int twips = (int)(20*ParseUnitArgument(val));
  4486.       CurrentTextWidth = twips;
  4487.  
  4488.       // Need to set an implicit right margin
  4489.       CurrentRightMarginOdd = PageWidth - CurrentTextWidth - CurrentLeftMarginOdd;
  4490.       CurrentRightMarginEven = PageWidth - CurrentTextWidth - CurrentLeftMarginEven;
  4491.       CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  4492.       sprintf(buf, "\\margr%d\n", CurrentRightMarginOdd);
  4493.       TexOutput(buf);
  4494.     }
  4495.     return FALSE;
  4496.   }
  4497.   case ltMARGINPAR:
  4498.   case ltMARGINPARODD:
  4499.   {
  4500.     if (start)
  4501.     {
  4502.       if (winHelp)
  4503.       {
  4504.         TexOutput("\\box\n");
  4505.         PushEnvironmentStyle("\\box");
  4506.       }
  4507.       else
  4508.       {
  4509.         sprintf(buf, "\\phpg\\posx%d\\absw%d\n", CurrentMarginParX, CurrentMarginParWidth);
  4510.         TexOutput(buf);
  4511.       }
  4512.       return TRUE;
  4513.     }
  4514.     else
  4515.     {
  4516.       if (winHelp)
  4517.       {
  4518.         TexOutput("\\par\\pard\n");
  4519.         PopEnvironmentStyle();
  4520.         WriteEnvironmentStyles();
  4521.       }
  4522.       else
  4523.         TexOutput("\\par\\pard\n");
  4524.       issuedNewParagraph = 1;
  4525.     }
  4526.     return FALSE;
  4527.   }
  4528.   case ltMARGINPAREVEN:
  4529.   {
  4530.     if (start)
  4531.     {
  4532.       if (winHelp)
  4533.       {
  4534.         TexOutput("\\box\n");
  4535.         PushEnvironmentStyle("\\box");
  4536.       }
  4537.       else
  4538.       {
  4539.         if (mirrorMargins)
  4540.         {
  4541.           // Have to calculate what the margins are changed to in WfW margin
  4542.           // mirror mode, on an even (left-hand) page.
  4543.           int x = PageWidth - CurrentRightMarginOdd - CurrentMarginParWidth - CurrentMarginParSep
  4544.                     - CurrentTextWidth + GutterWidth;
  4545.           sprintf(buf, "\\phpg\\posx%d\\absw%d\n", x, CurrentMarginParWidth);
  4546.           TexOutput(buf);
  4547.         }
  4548.         else
  4549.         {
  4550.           sprintf(buf, "\\phpg\\posx%d\\absw%d\n", CurrentMarginParX, CurrentMarginParWidth);
  4551.           TexOutput(buf);
  4552.         }
  4553.       }
  4554.       return TRUE;
  4555.     }
  4556.     else
  4557.     {
  4558.       if (winHelp)
  4559.       {
  4560.         TexOutput("\\par\\pard\n");
  4561.         PopEnvironmentStyle();
  4562.         WriteEnvironmentStyles();
  4563.       }
  4564.       else
  4565.         issuedNewParagraph = 1;
  4566.       TexOutput("\\par\\pard\n");
  4567.     }
  4568.     return FALSE;
  4569.   }
  4570.   case ltTWOCOLWIDTHA:
  4571.   {
  4572.     if (start)
  4573.     {
  4574.       char *val = GetArgData();
  4575.       int twips = (int)(20*ParseUnitArgument(val));
  4576.       TwoColWidthA = twips;
  4577.     }
  4578.     return FALSE;
  4579.     break;
  4580.   }
  4581.   case ltTWOCOLWIDTHB:
  4582.   {
  4583.     if (start)
  4584.     {
  4585.       char *val = GetArgData();
  4586.       int twips = (int)(20*ParseUnitArgument(val));
  4587.       TwoColWidthB = twips;
  4588.     }
  4589.     return FALSE;
  4590.     break;
  4591.   }
  4592.   case ltROW:
  4593.   case ltRULEDROW:
  4594.   {
  4595.     if (start)
  4596.     {
  4597.       int currentWidth = 0;
  4598.  
  4599.       if (!compatibilityMode || (currentRowNumber > 0))
  4600.       {
  4601.       TexOutput("\\pard\\intbl");
  4602.  
  4603.       if (macroId == ltRULEDROW)
  4604.         ruleBottom = 1;
  4605.       for (int i = 0; i < noColumns; i++)
  4606.       {
  4607.         currentWidth += TableData[i].width;
  4608.         if (ruleTop == 1)
  4609.         {
  4610.           TexOutput("\\clbrdrt\\brdrs\\brdrw15");
  4611.         }
  4612.         else if (ruleTop > 1)
  4613.         {
  4614.           TexOutput("\\clbrdrt\\brdrdb\\brdrw15");
  4615.         }
  4616.         if (ruleBottom == 1)
  4617.         {
  4618.           TexOutput("\\clbrdrb\\brdrs\\brdrw15");
  4619.         }
  4620.         else if (ruleBottom > 1)
  4621.         {
  4622.           TexOutput("\\clbrdrb\\brdrdb\\brdrw15");
  4623.         }
  4624.  
  4625.         if (TableData[i].rightBorder)
  4626.           TexOutput("\\clbrdrr\\brdrs\\brdrw15");
  4627.  
  4628.         if (TableData[i].leftBorder)
  4629.           TexOutput("\\clbrdrl\\brdrs\\brdrw15");
  4630.           
  4631.         sprintf(buf, "\\cellx%d", currentWidth);
  4632.         TexOutput(buf);
  4633.       }
  4634.       TexOutput("\\pard\\intbl\n");
  4635.       }
  4636.       ruleTop = 0;
  4637.       ruleBottom = 0;
  4638.       currentRowNumber ++;
  4639.       return TRUE;
  4640.     }
  4641.     else
  4642.     {
  4643. //      TexOutput("\\cell\\row\\trowd\\trgaph108\\trleft-108\n");
  4644.       TexOutput("\\cell\\row\\trowd\\trgaph108\n");
  4645.     }
  4646.     break;
  4647.   }
  4648.   case ltMULTICOLUMN:
  4649.   {
  4650.     static int noMultiColumns = 0;
  4651.     if (start)
  4652.     {
  4653.       switch (arg_no)
  4654.       {
  4655.         case 1:
  4656.         {
  4657.           noMultiColumns = atoi(GetArgData());
  4658.           return FALSE;
  4659.           break;
  4660.         }
  4661.         case 2:
  4662.         {
  4663.           return FALSE;
  4664.         }
  4665.         case 3:
  4666.         {
  4667.           return TRUE;
  4668.         }
  4669.       }
  4670.     }
  4671.     else
  4672.     {
  4673.       if (arg_no == 3)
  4674.       {
  4675.         for (int i = 1; i < noMultiColumns; i ++)
  4676.           TexOutput("\\cell");
  4677.       }
  4678.     }
  4679.     break;
  4680.   }
  4681.   case ltINDENTED:
  4682.   {
  4683.     if (start && (arg_no == 1))
  4684.     {
  4685. //      indentLevel ++;
  4686. //      TexOutput("\\fi0\n");
  4687.       int oldIndent = 0;
  4688.       wxNode *node = itemizeStack.First();
  4689.       if (node)
  4690.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  4691.  
  4692.       int indentValue = 20*ParseUnitArgument(GetArgData());
  4693.       int indentSize = indentValue + oldIndent;
  4694.  
  4695.       ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
  4696.       itemizeStack.Insert(struc);
  4697.       
  4698.       sprintf(buf, "\\tx%d\\li%d ", indentSize, indentSize);
  4699.       PushEnvironmentStyle(buf);
  4700.       TexOutput(buf);
  4701.       return FALSE;
  4702.     }
  4703.     if (!start && (arg_no == 2))
  4704.     {
  4705.       PopEnvironmentStyle();
  4706.       if (itemizeStack.First())
  4707.       {
  4708.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  4709.         delete struc;
  4710.         delete itemizeStack.First();
  4711.       }
  4712.       if (itemizeStack.Number() == 0)
  4713.       {
  4714.         TexOutput("\\par\\pard\n");
  4715.         issuedNewParagraph = 1;
  4716.         WriteEnvironmentStyles();
  4717.       }
  4718.     }
  4719.     return TRUE;
  4720.     break;
  4721.   }
  4722. /*
  4723.   case ltSIZEDBOX:
  4724.   case ltSIZEDBOXD:
  4725.   {
  4726.     if (start && (arg_no == 1))
  4727.     {
  4728.       int oldIndent = 0;
  4729.       wxNode *node = itemizeStack.First();
  4730.       if (node)
  4731.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  4732.  
  4733.       int boxWidth = 20*ParseUnitArgument(GetArgData());
  4734.  
  4735.       int indentValue = (int)((CurrentTextWidth - oldIndent - boxWidth)/2.0);
  4736.       int indentSize = indentValue + oldIndent;
  4737.       int indentSizeRight = indentSize + boxWidth;
  4738.  
  4739.       ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
  4740.       itemizeStack.Insert(struc);
  4741.       
  4742.       sprintf(buf, "\\tx%d\\li%d\\lr%d\\box%s ", indentSize, indentSize, indentSizeRight,
  4743.         ((macroId == ltCENTEREDBOX) ? "\\brdrs" : "\\brdrdb"));
  4744.       PushEnvironmentStyle(buf);
  4745.       TexOutput(buf);
  4746.       return FALSE;
  4747.     }
  4748.     if (!start && (arg_no == 2))
  4749.     {
  4750.       PopEnvironmentStyle();
  4751.       if (itemizeStack.First())
  4752.       {
  4753.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  4754.         delete struc;
  4755.         delete itemizeStack.First();
  4756.       }
  4757.       if (itemizeStack.Number() == 0)
  4758.       {
  4759.         TexOutput("\\par\\pard\n");
  4760.         issuedNewParagraph = 1;
  4761.         WriteEnvironmentStyles();
  4762.       }
  4763.     }
  4764.     return TRUE;
  4765.     break;
  4766.   }
  4767. */
  4768.   case ltDOCUMENTSTYLE:
  4769.   {
  4770.     DefaultOnArgument(macroId, arg_no, start);
  4771.     if (!start && !IsArgOptional())
  4772.     {
  4773.       if (MinorDocumentStyleString)
  4774.       {
  4775.         if (StringMatch("twoside", MinorDocumentStyleString))
  4776.           // Mirror margins, switch on odd/even headers & footers, and break sections at odd pages
  4777.           TexOutput("\\margmirror\\facingp\\sbkodd");
  4778.         if (StringMatch("twocolumn", MinorDocumentStyleString))
  4779.           TexOutput("\\cols2");
  4780.       }
  4781.       TexOutput("\n");
  4782.     }
  4783.     return FALSE;
  4784.   }
  4785.   case ltSETHOTSPOTCOLOUR:
  4786.   case ltSETHOTSPOTCOLOR:
  4787.   {
  4788.     if (!start)
  4789.     {
  4790.       char *text = GetArgData();
  4791.       if (strcmp(text, "yes") == 0 || strcmp(text, "on") == 0 || strcmp(text, "ok") == 0)
  4792.         hotSpotColour = TRUE;
  4793.       else
  4794.         hotSpotColour = FALSE;
  4795.     }
  4796.     return FALSE;
  4797.   }
  4798.   case ltSETTRANSPARENCY:
  4799.   {
  4800.     if (!start)
  4801.     {
  4802.       char *text = GetArgData();
  4803.       if (strcmp(text, "yes") == 0 || strcmp(text, "on") == 0 || strcmp(text, "ok") == 0)
  4804.         bitmapTransparency = TRUE;
  4805.       else
  4806.         bitmapTransparency = FALSE;
  4807.     }
  4808.     return FALSE;
  4809.   }
  4810.   case ltSETHOTSPOTUNDERLINE:
  4811.   {
  4812.     if (!start)
  4813.     {
  4814.       char *text = GetArgData();
  4815.       if (strcmp(text, "yes") == 0 || strcmp(text, "on") == 0 || strcmp(text, "ok") == 0)
  4816.         hotSpotUnderline = TRUE;
  4817.       else
  4818.         hotSpotUnderline = FALSE;
  4819.     }
  4820.     return FALSE;
  4821.   }
  4822.   case ltBIBITEM:
  4823.   {
  4824.     if (arg_no == 1 && start)
  4825.     {
  4826.       char *citeKey = GetArgData();
  4827.       TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
  4828.       if (ref)
  4829.       {
  4830.         if (ref->sectionNumber) delete[] ref->sectionNumber;
  4831.         sprintf(buf, "[%d]", citeCount);
  4832.         ref->sectionNumber = copystring(buf);
  4833.       }
  4834.  
  4835.       TexOutput("\\li260\\fi-260 "); // Indent from 2nd line
  4836.       sprintf(buf, "{\\b [%d]} ", citeCount);
  4837.       TexOutput(buf);
  4838.       citeCount ++;
  4839.       return FALSE;
  4840.     }
  4841.     if (arg_no == 2 && !start)
  4842.       TexOutput("\\par\\pard\\par\n\n");
  4843.     return TRUE;
  4844.     break;
  4845.   }
  4846.   case ltTHEBIBLIOGRAPHY:
  4847.   {
  4848.     if (start && (arg_no == 1))
  4849.     {
  4850.       citeCount = 1;
  4851.       if (winHelp)
  4852.         SetCurrentOutputs(Contents, Chapters);
  4853.  
  4854.       if (!winHelp)
  4855.       {
  4856.         fprintf(Chapters, "\\sect\\pgncont\\titlepg\n");
  4857.  
  4858.         // If a non-custom page style, we generate the header now.
  4859.         if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
  4860.                           strcmp(PageStyle, "empty") == 0 ||
  4861.                           strcmp(PageStyle, "headings") == 0))
  4862.         {
  4863.           OutputRTFHeaderCommands();
  4864.           OutputRTFFooterCommands();
  4865.         }
  4866.         
  4867.         // Need to reset the current numbering style, or RTF forgets it.
  4868.         OutputNumberStyle(currentNumberStyle);
  4869.         SetCurrentOutput(Contents);
  4870.       }
  4871.       else
  4872.         fprintf(Chapters, "\\page\n");
  4873.  
  4874.       if (winHelp)
  4875.         fprintf(Contents, "\n{\\uldb %s}", ReferencesNameString);
  4876.       else
  4877.         fprintf(Contents, "\\par\n\\pard{\\b %s}", ReferencesNameString);
  4878.  
  4879.       startedSections = TRUE;
  4880.  
  4881.       if (winHelp)
  4882.         fprintf(Chapters, "\n${\\footnote %s}", ReferencesNameString);
  4883.  
  4884.       char *topicName = "bibliography";
  4885.  
  4886.       if (winHelp)
  4887.         fprintf(Contents, "{\\v %s}\\par\\pard\n", topicName);
  4888.       else
  4889.         fprintf(Contents, "\\par\\par\\pard\n");
  4890.  
  4891.       if (winHelp)
  4892.       {
  4893.         fprintf(Chapters, "\n#{\\footnote %s}\n", topicName);
  4894.         fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
  4895.         fprintf(Chapters, "K{\\footnote {K} %s}\n", ReferencesNameString);
  4896.         GenerateKeywordsForTopic(topicName);
  4897.         if (useUpButton)
  4898.         {
  4899.           fprintf(Chapters, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  4900.                FileNameFromPath(FileRoot), "Contents");
  4901.         }
  4902.       }
  4903.       
  4904.       SetCurrentOutput(Chapters);
  4905.       char *styleCommand = "";
  4906.       if (!winHelp && useHeadingStyles)
  4907.         styleCommand = "\\s1";
  4908.       fprintf(Chapters, "\\pard{%s", (winHelp ? "\\keepn\\sa140\\sb140" : styleCommand));
  4909.       WriteHeadingStyle(Chapters, 1);  fprintf(Chapters, " References\\par\\pard}\n");
  4910.  
  4911.       return FALSE;
  4912.     }
  4913.     return TRUE;
  4914.     break;
  4915.   }
  4916.   case ltINDEX:
  4917.   {
  4918.     /*
  4919.      * In Windows help, all keywords should be at the start of the
  4920.      * topic, but Latex \index commands can be anywhere in the text.
  4921.      * So we're going to have to build up lists of keywords for a topic,
  4922.      * and insert them on the second pass.
  4923.      *
  4924.      * In linear RTF, we can embed the index entry now.
  4925.      *
  4926.      */
  4927.     if (start)
  4928.     {
  4929. //      char *entry = GetArgData();
  4930.       char buf[300];
  4931.       OutputChunkToString(GetArgChunk(), buf);
  4932.       if (winHelp)
  4933.       {
  4934.         if (CurrentTopic)
  4935.         {
  4936.           AddKeyWordForTopic(CurrentTopic, buf);
  4937.         }
  4938.       }
  4939.       else GenerateIndexEntry(buf);
  4940.     }
  4941.     return FALSE;
  4942.     break;
  4943.   }
  4944.   case ltFCOL:
  4945.   case ltBCOL:
  4946.   {
  4947.     if (start)
  4948.     {
  4949.       switch (arg_no)
  4950.       {
  4951.         case 1:
  4952.         {
  4953.           char *name = GetArgData();
  4954.           int pos = FindColourPosition(name);
  4955.           if (pos > -1)
  4956.           {
  4957.             sprintf(buf, "{%s%d ", ((macroId == ltFCOL) ? "\\cf" : "\\cb"), pos);
  4958.             TexOutput(buf);
  4959.           }
  4960.           else
  4961.           {
  4962.             sprintf(buf, "Could not find colour name %s", name);
  4963.             OnError(buf);
  4964.           }
  4965.           break;
  4966.         }
  4967.         case 2:
  4968.         {
  4969.           return TRUE;
  4970.           break;
  4971.         }
  4972.         default:
  4973.           break;
  4974.       }
  4975.     }
  4976.     else
  4977.     {
  4978.       if (arg_no == 2) TexOutput("}");
  4979.     }
  4980.     return FALSE;
  4981.     break;
  4982.   }
  4983.   case ltLABEL:
  4984.   {
  4985.     if (start && !winHelp && useWord)
  4986.     {
  4987.       char *s = GetArgData();
  4988.       // Only insert a bookmark here if it's not just been inserted
  4989.       // in a section heading.
  4990.       if ( !CurrentTopic || !(strcmp(CurrentTopic, s) == 0) )
  4991. /*
  4992.       if ( (!CurrentChapterName || !(CurrentChapterName && (strcmp(CurrentChapterName, s) == 0))) &&
  4993.            (!CurrentSectionName || !(CurrentSectionName && (strcmp(CurrentSectionName, s) == 0))) &&
  4994.            (!CurrentSubsectionName || !(CurrentSubsectionName && (strcmp(CurrentSubsectionName, s) == 0)))
  4995.          )
  4996. */
  4997.       {
  4998.           fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", s,s);
  4999.       }
  5000.     }
  5001.     return FALSE;
  5002.     break;
  5003.   }
  5004.   case ltPAGEREF:
  5005.   {
  5006.     if (start && useWord && !winHelp)
  5007.     {
  5008.       char *s = GetArgData();
  5009.       fprintf(Chapters, "{\\field{\\*\\fldinst  PAGEREF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}",
  5010.               s);
  5011.     }
  5012.     return FALSE;
  5013.     break;
  5014.   }
  5015.   case ltPOPREFONLY:
  5016.   {
  5017.     if (start)
  5018.       inPopRefSection = TRUE;
  5019.     else
  5020.       inPopRefSection = FALSE;
  5021.     break;
  5022.   }
  5023.   case ltINSERTATLEVEL:
  5024.   {
  5025.     // This macro allows you to insert text at a different level
  5026.     // from the current level, e.g. into the Sections from within a subsubsection.
  5027.     if (!winHelp & useWord)
  5028.         return FALSE;
  5029.     static int currentLevelNo = 1;
  5030.     static FILE* oldLevelFile = Chapters;
  5031.     if (start)
  5032.     {
  5033.       switch (arg_no)
  5034.       {
  5035.         case 1:
  5036.         {
  5037.           oldLevelFile = CurrentOutput1;
  5038.  
  5039.           char *str = GetArgData();
  5040.           currentLevelNo = atoi(str);
  5041.           FILE* outputFile;
  5042.           // TODO: cope with article style (no chapters)
  5043.           switch (currentLevelNo)
  5044.           {
  5045.             case 1:
  5046.             {
  5047.                 outputFile = Chapters;
  5048.                 break;
  5049.             }
  5050.             case 2:
  5051.             {
  5052.                 outputFile = Sections;
  5053.                 break;
  5054.             }
  5055.             case 3:
  5056.             {
  5057.                 outputFile = Subsections;
  5058.                 break;
  5059.             }
  5060.             case 4:
  5061.             {
  5062.                 outputFile = Subsubsections;
  5063.                 break;
  5064.             }
  5065.             default:
  5066.             {
  5067.                 outputFile = NULL;
  5068.                 break;
  5069.             }
  5070.           }
  5071.           if (outputFile)
  5072.             CurrentOutput1 = outputFile;
  5073.           return FALSE;
  5074.           break;
  5075.         }
  5076.         case 2:
  5077.         {
  5078.           return TRUE;
  5079.           break;
  5080.         }
  5081.         default:
  5082.           break;
  5083.       }
  5084.       return TRUE;
  5085.     }
  5086.     else
  5087.     {
  5088.         if (arg_no == 2)
  5089.         {
  5090.             CurrentOutput1 = oldLevelFile;
  5091.         }
  5092.         return TRUE;
  5093.     }
  5094.     break;
  5095.   }
  5096.   default:
  5097.   {
  5098.     return DefaultOnArgument(macroId, arg_no, start);
  5099.     break;
  5100.   }
  5101.   }
  5102.   return TRUE;
  5103. }
  5104.  
  5105. bool RTFGo(void)
  5106. {
  5107.   if (stopRunning)
  5108.       return FALSE;
  5109.  
  5110.   // Reset variables
  5111.   indentLevel = 0;
  5112.   forbidParindent = 0;
  5113.   contentsLineSection = NULL;
  5114.   contentsLineValue = NULL;
  5115.   descriptionItemArg = NULL;
  5116.   inTabular = FALSE;
  5117.   inTable = FALSE;
  5118.   inFigure = FALSE;
  5119.   startRows = FALSE;
  5120.   tableVerticalLineLeft = FALSE;
  5121.   tableVerticalLineRight = FALSE;
  5122.   noColumns = 0;
  5123.   startedSections = FALSE;
  5124.   inVerbatim = FALSE;
  5125.   browseId = 0;
  5126.   
  5127.   if (InputFile && OutputFile)
  5128.   {
  5129.     // Do some RTF-specific transformations on all the strings,
  5130.     // recursively
  5131.     Text2RTF(GetTopLevelChunk());
  5132.  
  5133.     Contents = fopen(TmpContentsName, "w");
  5134.     Chapters = fopen("chapters.rtf", "w");
  5135.     if (winHelp)
  5136.     {
  5137.       Sections = fopen("sections.rtf", "w");
  5138.       Subsections = fopen("subsections.rtf", "w");
  5139.       Subsubsections = fopen("subsubsections.rtf", "w");
  5140.       Popups = fopen("popups.rtf", "w");
  5141.       if (winHelpContents)
  5142.       {
  5143.         WinHelpContentsFile = fopen(WinHelpContentsFileName, "w");
  5144.         if (WinHelpContentsFile)
  5145.           fprintf(WinHelpContentsFile, ":Base %s.hlp\n", wxFileNameFromPath(FileRoot));
  5146.       }
  5147.  
  5148.       if (!Sections || !Subsections || !Subsubsections || !Popups || (winHelpContents && !WinHelpContentsFile))
  5149.       {
  5150.         OnError("Ouch! Could not open temporary file(s) for writing.");
  5151.         return FALSE;
  5152.       }
  5153.     }
  5154.     if (!Contents || !Chapters)
  5155.     {
  5156.       OnError("Ouch! Could not open temporary file(s) for writing.");
  5157.       return FALSE;
  5158.     }
  5159.  
  5160.     if (winHelp)
  5161.     {
  5162.       fprintf(Chapters, "\n#{\\footnote Contents}\n");
  5163.       fprintf(Chapters, "${\\footnote Contents}\n");
  5164.       fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
  5165.       fprintf(Chapters, "K{\\footnote {K} %s}\n", ContentsNameString);
  5166.       fprintf(Chapters, "!{\\footnote DisableButton(\"Up\")}\n");
  5167.     }
  5168.     if (!winHelp)
  5169.     {
  5170.       fprintf(Chapters, "\\titlepg\n");
  5171.       fprintf(Contents, "\\par\\pard\\pgnrestart\\sect\\titlepg");
  5172.     }
  5173.     
  5174.     // In WinHelp, Contents title takes font of title.
  5175.     // In linear RTF, same as chapter headings.
  5176.     fprintf(Contents, "{\\b\\fs%d %s}\\par\\par\\pard\n\n",
  5177.       (winHelp ? titleFont : chapterFont)*2, ContentsNameString);
  5178.  
  5179.     // By default, Swiss, 10 point.
  5180.     fprintf(Chapters, "\\f2\\fs20\n");
  5181.  
  5182.     SetCurrentOutput(Chapters);
  5183.  
  5184.     if (stopRunning)
  5185.         return FALSE;
  5186.  
  5187.     OnInform("Converting...");
  5188.  
  5189.     TraverseDocument();
  5190.  
  5191.     FILE *Header = fopen("header.rtf", "w");
  5192.     if (!Header)
  5193.     {
  5194.       OnError("Ouch! Could not open temporary file header.rtf for writing.");
  5195.       return FALSE;
  5196.     }
  5197.     WriteRTFHeader(Header);
  5198.     fclose(Header); Header = NULL;
  5199.     
  5200.     Tex2RTFYield(TRUE);
  5201.     if (winHelp)
  5202.     {
  5203. //      fprintf(Contents, "\\page\n");
  5204.       fprintf(Chapters, "\\page\n");
  5205.       fprintf(Sections, "\\page\n");
  5206.       fprintf(Subsections, "\\page\n");
  5207.       fprintf(Subsubsections, "\\page\n\n");
  5208.       fprintf(Popups, "\\page\n}\n");
  5209.     }
  5210.  
  5211. //    TexOutput("\n\\info{\\doccomm Document created by Julian Smart's Tex2RTF.}\n");
  5212.     if (!winHelp)
  5213.       TexOutput("}\n");
  5214.     fclose(Contents); Contents = NULL;
  5215.     fclose(Chapters); Chapters = NULL;
  5216.     if (winHelp)
  5217.     {
  5218.       fclose(Sections); Sections = NULL;
  5219.       fclose(Subsections); Subsections = NULL;
  5220.       fclose(Subsubsections); Subsubsections = NULL;
  5221.       fclose(Popups); Popups = NULL;
  5222.       if (winHelpContents)
  5223.       {
  5224.         fclose(WinHelpContentsFile); WinHelpContentsFile = NULL;
  5225.       }
  5226.     }
  5227.  
  5228.     if (winHelp)
  5229.     {
  5230.       wxConcatFiles("header.rtf", "chapters.rtf", "tmp1.rtf");
  5231.       Tex2RTFYield(TRUE);
  5232.       wxConcatFiles("tmp1.rtf", "sections.rtf", "tmp2.rtf");
  5233.       Tex2RTFYield(TRUE);
  5234.       wxConcatFiles("tmp2.rtf", "subsections.rtf", "tmp3.rtf");
  5235.       Tex2RTFYield(TRUE);
  5236.       wxConcatFiles("tmp3.rtf", "subsubsections.rtf", "tmp4.rtf");
  5237.       Tex2RTFYield(TRUE);
  5238.       wxConcatFiles("tmp4.rtf", "popups.rtf", OutputFile);
  5239.       Tex2RTFYield(TRUE);
  5240.  
  5241.       wxRemoveFile("tmp1.rtf");
  5242.       wxRemoveFile("tmp2.rtf");
  5243.       wxRemoveFile("tmp3.rtf");
  5244.       wxRemoveFile("tmp4.rtf");
  5245.     }
  5246.     else
  5247.     {
  5248.       wxConcatFiles("header.rtf", "chapters.rtf", "tmp1.rtf");
  5249.       Tex2RTFYield(TRUE);
  5250.       if (FileExists(OutputFile))
  5251.           wxRemoveFile(OutputFile);
  5252.  
  5253.       char *cwdStr;
  5254.       cwdStr = wxGetWorkingDirectory();
  5255.  
  5256.       wxString outputDirStr;
  5257.       outputDirStr = wxPathOnly(OutputFile);
  5258.  
  5259.       // Determine if the temp file and the output file are in the same directory,
  5260.       // and if they are, then just rename the temp file rather than copying
  5261.       // it, as this is much faster when working with large (multi-megabyte files)
  5262.       if ((wxStrcmp(outputDirStr.c_str(),"") == 0) ||  // no path specified on output file
  5263.           (wxStrcmp(cwdStr,outputDirStr.c_str()) == 0)) // paths do not match
  5264.       {
  5265.         wxRenameFile("tmp1.rtf", OutputFile);
  5266.       }
  5267.       else
  5268.       {
  5269.         wxCopyFile("tmp1.rtf", OutputFile);
  5270.       }
  5271.       delete [] cwdStr;
  5272.       Tex2RTFYield(TRUE);
  5273.       wxRemoveFile("tmp1.rtf");
  5274.     }
  5275.     
  5276.     if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
  5277.  
  5278.     if (!wxRenameFile(TmpContentsName, ContentsName))
  5279.     {
  5280.       wxCopyFile(TmpContentsName, ContentsName);
  5281.       wxRemoveFile(TmpContentsName);
  5282.     }
  5283.  
  5284.     wxRemoveFile("chapters.rtf");
  5285.     wxRemoveFile("header.rtf");
  5286.       
  5287.     if (winHelp)
  5288.     {
  5289.       wxRemoveFile("sections.rtf");
  5290.       wxRemoveFile("subsections.rtf");
  5291.       wxRemoveFile("subsubsections.rtf");
  5292.       wxRemoveFile("popups.rtf");
  5293.     }
  5294.     if (winHelp && generateHPJ)
  5295.       WriteHPJ(OutputFile);
  5296.     return TRUE;
  5297.   }
  5298.   return FALSE;
  5299. }
  5300.