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 / htmlutil.cpp < prev    next >
C/C++ Source or Header  |  2002-08-21  |  80KB  |  3,293 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        htmlutil.cpp
  3. // Purpose:     Converts Latex to HTML
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     7.9.93
  7. // RCS-ID:      $Id: htmlutil.cpp,v 1.13 2002/06/03 19:30:15 JS 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 "table.h"
  30.  
  31.  
  32. extern wxHashTable TexReferences;
  33.  
  34.  
  35. extern void DecToHex(int, char *);
  36. void GenerateHTMLIndexFile(char *fname);
  37.  
  38. void GenerateHTMLWorkshopFiles(char *fname);
  39. void HTMLWorkshopAddToContents(int level, char *s, char *file);
  40. void HTMLWorkshopStartContents();
  41. void HTMLWorkshopEndContents();
  42.  
  43. void OutputContentsFrame(void);
  44.  
  45. #include "readshg.h" // Segmented hypergraphics parsing
  46.  
  47. char *ChaptersName = NULL;
  48. char *SectionsName = NULL;
  49. char *SubsectionsName = NULL;
  50. char *SubsubsectionsName = NULL;
  51. char *TitlepageName = NULL;
  52. char *lastFileName = NULL;
  53. char *lastTopic = NULL;
  54. char *currentFileName = NULL;
  55. char *contentsFrameName = NULL;
  56.  
  57. static TexChunk *descriptionItemArg = NULL;
  58. static TexChunk *helpRefFilename = NULL;
  59. static TexChunk *helpRefText = NULL;
  60. static int indentLevel = 0;
  61. static int citeCount = 1;
  62. extern FILE *Contents;
  63. FILE *FrameContents = NULL;
  64. FILE *Titlepage = NULL;
  65. // FILE *FrameTitlepage = NULL;
  66. int fileId = 0;
  67. bool subsectionStarted = FALSE;
  68.  
  69. // Which column of a row are we in? (Assumes no nested tables, of course)
  70. int currentColumn = 0;
  71.  
  72. // Are we in verbatim mode? If so, format differently.
  73. static bool inVerbatim = FALSE;
  74.  
  75. // Need to know whether we're in a table or figure for benefit
  76. // of listoffigures/listoftables
  77. static bool inFigure = FALSE;
  78. static bool inTable = FALSE;
  79.  
  80. // This is defined in the Tex2Any library.
  81. extern char *BigBuffer;
  82.  
  83. // DHS Two-column table dimensions.
  84. static int TwoColWidthA = -1;
  85. static int TwoColWidthB = -1;
  86.  
  87.  
  88. class HyperReference: public wxObject
  89. {
  90.  public:
  91.   char *refName;
  92.   char *refFile;
  93.   HyperReference(char *name, char *file)
  94.   {
  95.     if (name) refName = copystring(name);
  96.     if (file) refFile = copystring(file);
  97.   }
  98. };
  99.  
  100. class TexNextPage: public wxObject
  101. {
  102.  public:
  103.   char *label;
  104.   char *filename;
  105.   TexNextPage(char *theLabel, char *theFile)
  106.   {
  107.     label = copystring(theLabel);
  108.     filename = copystring(theFile);
  109.   }
  110.   ~TexNextPage(void)
  111.   {
  112.     delete[] label;
  113.     delete[] filename;
  114.   }
  115. };
  116.  
  117. wxHashTable TexNextPages(wxKEY_STRING);
  118.  
  119. static char *CurrentChapterName = NULL;
  120. static char *CurrentChapterFile = NULL;
  121. static char *CurrentSectionName = NULL;
  122. static char *CurrentSectionFile = NULL;
  123. static char *CurrentSubsectionName = NULL;
  124. static char *CurrentSubsectionFile = NULL;
  125. static char *CurrentSubsubsectionName = NULL;
  126. static char *CurrentSubsubsectionFile = NULL;
  127. static char *CurrentTopic = NULL;
  128.  
  129. static void SetCurrentTopic(char *s)
  130. {
  131.   if (CurrentTopic) delete[] CurrentTopic;
  132.   CurrentTopic = copystring(s);
  133. }
  134.  
  135. void SetCurrentChapterName(char *s, char *file)
  136. {
  137.   if (CurrentChapterName) delete[] CurrentChapterName;
  138.   CurrentChapterName = copystring(s);
  139.   if (CurrentChapterFile) delete[] CurrentChapterFile;
  140.   CurrentChapterFile = copystring(file);
  141.  
  142.   currentFileName = CurrentChapterFile;
  143.  
  144.   SetCurrentTopic(s);
  145. }
  146. void SetCurrentSectionName(char *s, char *file)
  147. {
  148.   if (CurrentSectionName) delete[] CurrentSectionName;
  149.   CurrentSectionName = copystring(s);
  150.   if (CurrentSectionFile) delete[] CurrentSectionFile;
  151.   CurrentSectionFile = copystring(file);
  152.  
  153.   currentFileName = CurrentSectionFile;
  154.   SetCurrentTopic(s);
  155. }
  156. void SetCurrentSubsectionName(char *s, char *file)
  157. {
  158.   if (CurrentSubsectionName) delete[] CurrentSubsectionName;
  159.   CurrentSubsectionName = copystring(s);
  160.   if (CurrentSubsectionFile) delete[] CurrentSubsectionFile;
  161.   CurrentSubsectionFile = copystring(file);
  162.   currentFileName = CurrentSubsectionFile;
  163.   SetCurrentTopic(s);
  164. }
  165. void SetCurrentSubsubsectionName(char *s, char *file)
  166. {
  167.   if (CurrentSubsubsectionName) delete[] CurrentSubsubsectionName;
  168.   CurrentSubsubsectionName = copystring(s);
  169.   if (CurrentSubsubsectionFile) delete[] CurrentSubsubsectionFile;
  170.   CurrentSubsubsectionFile = copystring(file);
  171.   currentFileName = CurrentSubsubsectionFile;
  172.   SetCurrentTopic(s);
  173. }
  174.  
  175. /*
  176.  * Close former filedescriptor and reopen using another filename.
  177.  *
  178.  */
  179.  
  180. void ReopenFile(FILE **fd, char **fileName)
  181. {
  182.   if (*fd)
  183.   {
  184.     fprintf(*fd, "\n</FONT></BODY></HTML>\n");
  185.     fclose(*fd);
  186.   }
  187.   fileId ++;
  188.   char buf[400];
  189.   if (truncateFilenames)
  190.     sprintf(buf, "%s%d.htm", FileRoot, fileId);
  191.   else
  192.     sprintf(buf, "%s%d.html", FileRoot, fileId);
  193.   if (*fileName) delete[] *fileName;
  194.   *fileName = copystring(FileNameFromPath(buf));
  195.   *fd = fopen(buf, "w");
  196.   fprintf(*fd, "<HTML>\n");
  197. }
  198.  
  199. /*
  200.  * Reopen section contents file, i.e. the index appended to each section
  201.  * in subsectionCombine mode
  202.  */
  203.  
  204. static char *SectionContentsFilename = NULL;
  205. static FILE *SectionContentsFD = NULL;
  206.  
  207. void ReopenSectionContentsFile(void)
  208. {
  209.     if ( SectionContentsFD )
  210.     {
  211.         fclose(SectionContentsFD);
  212.     }
  213.     if ( SectionContentsFilename )
  214.         delete[] SectionContentsFilename;
  215.     SectionContentsFD = NULL;
  216.     SectionContentsFilename = NULL;
  217.  
  218.     // Create the name from the current section filename
  219.     if ( CurrentSectionFile )
  220.     {
  221.         char buf[256];
  222.         strcpy(buf, CurrentSectionFile);
  223.         wxStripExtension(buf);
  224.         strcat(buf, ".con");
  225.         SectionContentsFilename = copystring(buf);
  226.  
  227.         SectionContentsFD = fopen(SectionContentsFilename, "w");
  228.     }
  229. }
  230.  
  231.  
  232. /*
  233.  * Given a TexChunk with a string value, scans through the string
  234.  * converting Latex-isms into HTML-isms, such as 2 newlines -> <P>.
  235.  *
  236.  */
  237.  
  238. void ProcessText2HTML(TexChunk *chunk)
  239. {
  240.   bool changed = FALSE;
  241.   int ptr = 0;
  242.   int i = 0;
  243.   char ch = 1;
  244.   int len = strlen(chunk->value);
  245.   while (ch != 0)
  246.   {
  247.     ch = chunk->value[i];
  248.  
  249.     // 2 newlines means \par
  250.     if (!inVerbatim && chunk->value[i] == 10 && ((len > i+1 && chunk->value[i+1] == 10) ||
  251.                         ((len > i+1 && chunk->value[i+1] == 13) &&
  252.                         (len > i+2 && chunk->value[i+2] == 10))))
  253.     {
  254.       BigBuffer[ptr] = 0; strcat(BigBuffer, "<P>\n\n"); ptr += 5;
  255.       i += 2;
  256.       changed = TRUE;
  257.     }
  258.     else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
  259.     {
  260.       BigBuffer[ptr] = '"'; ptr ++;
  261.       i += 2;
  262.       changed = TRUE;
  263.     }
  264.     else if (!inVerbatim && ch == '`') // Change ` to '
  265.     {
  266.       BigBuffer[ptr] = 39; ptr ++;
  267.       i += 1;
  268.       changed = TRUE;
  269.     }
  270.     else if (ch == '<') // Change < to <
  271.     {
  272.       BigBuffer[ptr] = 0;
  273.       strcat(BigBuffer, "<");
  274.       ptr += 4;
  275.       i += 1;
  276.       changed = TRUE;
  277.     }
  278.     else if (ch == '>') // Change > to >
  279.     {
  280.       BigBuffer[ptr] = 0;
  281.       strcat(BigBuffer, ">");
  282.       ptr += 4;
  283.       i += 1;
  284.       changed = TRUE;
  285.     }
  286.     else
  287.     {
  288.       BigBuffer[ptr] = ch;
  289.       i ++;
  290.       ptr ++;
  291.     }
  292.   }
  293.   BigBuffer[ptr] = 0;
  294.  
  295.   if (changed)
  296.   {
  297.     delete chunk->value;
  298.     chunk->value = copystring(BigBuffer);
  299.   }
  300. }
  301.  
  302. /*
  303.  * Scan through all chunks starting from the given one,
  304.  * calling ProcessText2HTML to convert Latex-isms to RTF-isms.
  305.  * This should be called after Tex2Any has parsed the file,
  306.  * and before TraverseDocument is called.
  307.  *
  308.  */
  309.  
  310. void Text2HTML(TexChunk *chunk)
  311. {
  312.   Tex2RTFYield();
  313.   if (stopRunning) return;
  314.  
  315.   switch (chunk->type)
  316.   {
  317.     case CHUNK_TYPE_MACRO:
  318.     {
  319.       TexMacroDef *def = chunk->def;
  320.  
  321.       if (def && def->ignore)
  322.         return;
  323.  
  324.       if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL))
  325.         inVerbatim = TRUE;
  326.  
  327.       wxNode *node = chunk->children.First();
  328.       while (node)
  329.       {
  330.         TexChunk *child_chunk = (TexChunk *)node->Data();
  331.         Text2HTML(child_chunk);
  332.         node = node->Next();
  333.       }
  334.  
  335.       if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL))
  336.         inVerbatim = FALSE;
  337.  
  338.       break;
  339.     }
  340.     case CHUNK_TYPE_ARG:
  341.     {
  342.       wxNode *node = chunk->children.First();
  343.       while (node)
  344.       {
  345.         TexChunk *child_chunk = (TexChunk *)node->Data();
  346.         Text2HTML(child_chunk);
  347.         node = node->Next();
  348.       }
  349.  
  350.       break;
  351.     }
  352.     case CHUNK_TYPE_STRING:
  353.     {
  354.       if (chunk->value)
  355.         ProcessText2HTML(chunk);
  356.       break;
  357.     }
  358.   }
  359. }
  360.  
  361. /*
  362.  * Add appropriate browse buttons to this page.
  363.  *
  364.  */
  365.  
  366. void AddBrowseButtons(char *upLabel, char *upFilename,
  367.   char *previousLabel, char *previousFilename,
  368.   char *thisLabel, char *thisFilename)
  369. {
  370.   char contentsReferenceBuf[80];
  371.   char upReferenceBuf[80];
  372.   char backReferenceBuf[80];
  373.   char forwardReferenceBuf[80];
  374.   if (htmlBrowseButtons == HTML_BUTTONS_NONE)
  375.     return;
  376.  
  377.   char *contentsReference = NULL;
  378.   if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
  379.     contentsReference = ContentsNameString;
  380.   else
  381.   {
  382. //    contentsReference = "<img align=center src=\"contents.gif\" BORDER=0 ALT=\"Contents\">";
  383.     contentsReference = contentsReferenceBuf;
  384.     sprintf(contentsReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Contents\">", ConvertCase("contents.gif"));
  385.   }
  386.  
  387.   char *upReference = NULL;
  388.   if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
  389.     upReference = UpNameString;
  390.   else
  391.   {
  392. //    upReference = "<img align=center src=\"up.gif\" ALT=\"Up\">";
  393.     upReference = upReferenceBuf;
  394.     sprintf(upReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Up\">", ConvertCase("up.gif"));
  395.   }
  396.  
  397.   char *backReference = NULL;
  398.   if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
  399.     backReference = "<<";
  400.   else
  401.   {
  402. //    backReference = "<img align=center src=\"back.gif\" ALT=\"Previous\">";
  403.     backReference = backReferenceBuf;
  404.     sprintf(backReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Previous\">", ConvertCase("back.gif"));
  405.   }
  406.  
  407.   char *forwardReference = NULL;
  408.   if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
  409.     forwardReference = ">>";
  410.   else
  411.   {
  412. //    forwardReference = "<img align=center src=\"forward.gif\" ALT=\"Next\">";
  413.     forwardReference = forwardReferenceBuf;
  414.     sprintf(forwardReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Next\">", ConvertCase("forward.gif"));
  415.   }
  416.  
  417.   TexOutput("<CENTER>");
  418.  
  419.   char buf[200];
  420.  
  421.   /*
  422.    * Contents button
  423.    *
  424.    */
  425.  
  426.   if (truncateFilenames)
  427.   {
  428.     char buf1[80];
  429.     strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot)));
  430.     sprintf(buf, "\n<A HREF=\"%s.%s\">%s</A> ", buf1, ConvertCase("htm"), contentsReference);
  431.   }
  432.   else
  433.   {
  434.     char buf1[80];
  435.     strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot)));
  436.     sprintf(buf, "\n<A HREF=\"%s%s\">%s</A> ", buf1, ConvertCase("_contents.html"), contentsReference);
  437.   }
  438. //  TexOutput("<NOFRAMES>");
  439.   TexOutput(buf);
  440. //  TexOutput("</NOFRAMES>");
  441.  
  442.   /*
  443.    * Up button
  444.    *
  445.    */
  446.  
  447.   if (upLabel && upFilename)
  448.   {
  449.     if (strlen(upLabel) > 0)
  450.       sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(upFilename), upLabel, upReference);
  451.     else
  452.       sprintf(buf, "<A HREF=\"%s\">%s</A> ", ConvertCase(upFilename), upReference);
  453.     if (strcmp(upLabel, "contents") == 0)
  454.     {
  455. //      TexOutput("<NOFRAMES>");
  456.       TexOutput(buf);
  457. //      TexOutput("</NOFRAMES>");
  458.     }
  459.     else
  460.      TexOutput(buf);
  461.   }
  462.  
  463.   /*
  464.    * << button
  465.    *
  466.    */
  467.  
  468.   if (previousLabel && previousFilename)
  469.   {
  470.     sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(previousFilename), previousLabel, backReference);
  471.     if (strcmp(previousLabel, "contents") == 0)
  472.     {
  473. //      TexOutput("<NOFRAMES>");
  474.       TexOutput(buf);
  475. //      TexOutput("</NOFRAMES>");
  476.     }
  477.     else
  478.       TexOutput(buf);
  479.   }
  480.   else
  481.   {
  482.     // A placeholder so the buttons don't keep moving position
  483.     sprintf(buf, "%s ", backReference);
  484.     TexOutput(buf);
  485.   }
  486.  
  487.   char *nextLabel = NULL;
  488.   char *nextFilename = NULL;
  489.  
  490.   // Get the next page, and record the previous page's 'next' page
  491.   // (i.e. this page)
  492.   TexNextPage *nextPage = (TexNextPage *)TexNextPages.Get(thisLabel);
  493.   if (nextPage)
  494.   {
  495.     nextLabel = nextPage->label;
  496.     nextFilename = nextPage->filename;
  497.   }
  498.   if (previousLabel && previousFilename)
  499.   {
  500.     TexNextPage *oldNextPage = (TexNextPage *)TexNextPages.Get(previousLabel);
  501.     if (oldNextPage)
  502.     {
  503.       delete oldNextPage;
  504.       TexNextPages.Delete(previousLabel);
  505.     }
  506.     TexNextPage *newNextPage = new TexNextPage(thisLabel, thisFilename);
  507.     TexNextPages.Put(previousLabel, newNextPage);
  508.   }
  509.  
  510.   /*
  511.    * >> button
  512.    *
  513.    */
  514.  
  515.   if (nextLabel && nextFilename)
  516.   {
  517.     sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(nextFilename), nextLabel, forwardReference);
  518.     TexOutput(buf);
  519.   }
  520.   else
  521.   {
  522.     // A placeholder so the buttons don't keep moving position
  523.     sprintf(buf, "%s ", forwardReference);
  524.     TexOutput(buf);
  525.   }
  526.  
  527.   /*
  528.    * Horizontal rule to finish it off nicely.
  529.    *
  530.    */
  531.   TexOutput("</CENTER>");
  532.   TexOutput("<HR>\n");
  533.  
  534.   // Update last topic/filename
  535.   if (lastFileName)
  536.     delete[] lastFileName;
  537.   lastFileName = copystring(thisFilename);
  538.   if (lastTopic)
  539.     delete[] lastTopic;
  540.   lastTopic = copystring(thisLabel);
  541. }
  542.  
  543. // A colour string is either 3 numbers separated by semicolons (RGB),
  544. // or a reference to a GIF. Return the filename or a hex string like #934CE8
  545. char *ParseColourString(char *bkStr, bool *isPicture)
  546. {
  547.   static char resStr[300];
  548.   strcpy(resStr, bkStr);
  549.   char *tok1 = strtok(resStr, ";");
  550.   char *tok2 = strtok(NULL, ";");
  551.   if (tok1)
  552.   {
  553.     if (!tok2)
  554.     {
  555.       *isPicture = TRUE;
  556.       return resStr;
  557.     }
  558.     else
  559.     {
  560.       *isPicture = FALSE;
  561.       char *tok3 = strtok(NULL, ";");
  562.       if (tok3)
  563.       {
  564.         // Now convert 3 strings into decimal numbers, and then hex numbers.
  565.         int red = atoi(tok1);
  566.         int green = atoi(tok2);
  567.         int blue = atoi(tok3);
  568.  
  569.         strcpy(resStr, "#");
  570.  
  571.         char buf[3];
  572.         DecToHex(red, buf);
  573.         strcat(resStr, buf);
  574.         DecToHex(green, buf);
  575.         strcat(resStr, buf);
  576.         DecToHex(blue, buf);
  577.         strcat(resStr, buf);
  578.         return resStr;
  579.       }
  580.       else return NULL;
  581.     }
  582.   }
  583.   else return NULL;
  584. }
  585.  
  586. void OutputFont(void)
  587. {
  588.   // Output <FONT FACE=...>
  589.   TexOutput("<FONT FACE=\"");
  590.   if (htmlFaceName)
  591.     TexOutput(htmlFaceName);
  592.   else
  593.     TexOutput("Times New Roman");
  594.   TexOutput("\">\n");
  595. }
  596.  
  597. // Output start of <BODY> block
  598. void OutputBodyStart(void)
  599. {
  600.   TexOutput("\n<BODY");
  601.   if (backgroundImageString)
  602.   {
  603.     bool isPicture = FALSE;
  604.     char *s = ParseColourString(backgroundImageString, &isPicture);
  605.     if (s)
  606.     {
  607.       TexOutput(" BACKGROUND=\""); TexOutput(s); TexOutput("\"");
  608.     }
  609.   }
  610.   if (backgroundColourString)
  611.   {
  612.     bool isPicture = FALSE;
  613.     char *s = ParseColourString(backgroundColourString, &isPicture);
  614.     if (s)
  615.     {
  616.       TexOutput(" BGCOLOR="); TexOutput(s);
  617.     }
  618.   }
  619.  
  620.   // Set foreground text colour, if one is specified
  621.   if (textColourString)
  622.   {
  623.     bool isPicture = FALSE;
  624.     char *s = ParseColourString(textColourString, &isPicture);
  625.     if (s)
  626.     {
  627.       TexOutput(" TEXT="); TexOutput(s);
  628.     }
  629.   }
  630.   // Set link text colour, if one is specified
  631.   if (linkColourString)
  632.   {
  633.     bool isPicture = FALSE;
  634.     char *s = ParseColourString(linkColourString, &isPicture);
  635.     if (s)
  636.     {
  637.       TexOutput(" LINK="); TexOutput(s);
  638.     }
  639.   }
  640.   // Set followed link text colour, if one is specified
  641.   if (followedLinkColourString)
  642.   {
  643.     bool isPicture = FALSE;
  644.     char *s = ParseColourString(followedLinkColourString, &isPicture);
  645.     if (s)
  646.     {
  647.       TexOutput(" VLINK="); TexOutput(s);
  648.     }
  649.   }
  650.   TexOutput(">\n");
  651.  
  652.   OutputFont();
  653. }
  654.  
  655. void HTMLHead()
  656. {
  657.   TexOutput("<head>");
  658.   if (htmlStylesheet) {
  659.     TexOutput("<link rel=stylesheet type=\"text/css\" href=\"");
  660.     TexOutput(htmlStylesheet);
  661.     TexOutput("\">");
  662.   }
  663. };
  664.  
  665. void HTMLHeadTo(FILE* f)
  666. {
  667.   if (htmlStylesheet)
  668.     fprintf(f,"<head><link rel=stylesheet type=\"text/css\" href=\"%s\">",htmlStylesheet);
  669.   else
  670.     fprintf(f,"<head>");
  671. }
  672.  
  673. // Called on start/end of macro examination
  674. void HTMLOnMacro(int macroId, int no_args, bool start)
  675. {
  676.   switch (macroId)
  677.   {
  678.   case ltCHAPTER:
  679.   case ltCHAPTERSTAR:
  680.   case ltCHAPTERHEADING:
  681.   {
  682.     if (!start)
  683.     {
  684.       sectionNo = 0;
  685.       figureNo = 0;
  686.       subsectionNo = 0;
  687.       subsubsectionNo = 0;
  688.       if (macroId != ltCHAPTERSTAR)
  689.         chapterNo ++;
  690.  
  691.       SetCurrentOutput(NULL);
  692.       startedSections = TRUE;
  693.  
  694.       char *topicName = FindTopicName(GetNextChunk());
  695.       ReopenFile(&Chapters, &ChaptersName);
  696.       AddTexRef(topicName, ChaptersName, ChapterNameString);
  697.  
  698.       SetCurrentChapterName(topicName, ChaptersName);
  699.       if (htmlWorkshopFiles) HTMLWorkshopAddToContents(0, topicName, ChaptersName);
  700.  
  701.       SetCurrentOutput(Chapters);
  702.  
  703.       HTMLHead();
  704.       TexOutput("<title>");
  705.       OutputCurrentSection(); // Repeat section header
  706.       TexOutput("</title></head>\n");
  707.       OutputBodyStart();
  708.  
  709.       char titleBuf[200];
  710.       if (truncateFilenames)
  711.         sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
  712.       else
  713.         sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
  714.  
  715.       fprintf(Chapters, "<A NAME=\"%s\"></A>", topicName);
  716.  
  717.       AddBrowseButtons("", titleBuf, // Up
  718.                        lastTopic, lastFileName,  // Last topic
  719.                        topicName, ChaptersName); // This topic
  720.  
  721.       fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), topicName);
  722.  
  723.       if (htmlFrameContents && FrameContents)
  724.       {
  725.         SetCurrentOutput(FrameContents);
  726.         fprintf(FrameContents, "\n<LI><A HREF=\"%s#%s\" TARGET=\"mainwindow\">", ConvertCase(ChaptersName), topicName);
  727.         OutputCurrentSection();
  728.         fprintf(FrameContents, "</A>\n");
  729.       }
  730.  
  731.       SetCurrentOutputs(Contents, Chapters);
  732.       fprintf(Chapters, "\n<H2>");
  733.       OutputCurrentSection();
  734.       fprintf(Contents, "</A>\n");
  735.       fprintf(Chapters, "</H2>\n");
  736.  
  737.       SetCurrentOutput(Chapters);
  738.  
  739.       // Add this section title to the list of keywords
  740.       if (htmlIndex)
  741.       {
  742.         OutputCurrentSectionToString(wxTex2RTFBuffer);
  743.         AddKeyWordForTopic(topicName, wxTex2RTFBuffer, ConvertCase(currentFileName));
  744.       }
  745.     }
  746.     break;
  747.   }
  748.   case ltSECTION:
  749.   case ltSECTIONSTAR:
  750.   case ltSECTIONHEADING:
  751.   case ltGLOSS:
  752.   {
  753.     if (!start)
  754.     {
  755.       subsectionNo = 0;
  756.       subsubsectionNo = 0;
  757.       subsectionStarted = FALSE;
  758.  
  759.       if (macroId != ltSECTIONSTAR)
  760.         sectionNo ++;
  761.  
  762.       SetCurrentOutput(NULL);
  763.       startedSections = TRUE;
  764.  
  765.       char *topicName = FindTopicName(GetNextChunk());
  766.       ReopenFile(&Sections, &SectionsName);
  767.       AddTexRef(topicName, SectionsName, SectionNameString);
  768.  
  769.       SetCurrentSectionName(topicName, SectionsName);
  770.       if (htmlWorkshopFiles) HTMLWorkshopAddToContents(1, topicName, SectionsName);
  771.  
  772.       SetCurrentOutput(Sections);
  773.       HTMLHead();
  774.       TexOutput("<title>");
  775.       OutputCurrentSection();
  776.       TexOutput("</title></head>\n");
  777.       OutputBodyStart();
  778.  
  779.       fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
  780.       AddBrowseButtons(CurrentChapterName, CurrentChapterFile, // Up
  781.                        lastTopic, lastFileName,  // Last topic
  782.                        topicName, SectionsName); // This topic
  783.  
  784.       FILE *jumpFrom = ((DocumentStyle == LATEX_ARTICLE) ? Contents : Chapters);
  785.  
  786.       SetCurrentOutputs(jumpFrom, Sections);
  787.       if (DocumentStyle == LATEX_ARTICLE)
  788.         fprintf(jumpFrom, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(SectionsName), topicName);
  789.       else
  790.         fprintf(jumpFrom, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SectionsName), topicName);
  791.  
  792.       fprintf(Sections, "\n<H2>");
  793.       OutputCurrentSection();
  794.  
  795.       if (DocumentStyle == LATEX_ARTICLE)
  796.         fprintf(jumpFrom, "</A>\n");
  797.       else
  798.         fprintf(jumpFrom, "</B></A><BR>\n");
  799.       fprintf(Sections, "</H2>\n");
  800.  
  801.       SetCurrentOutput(Sections);
  802.       // Add this section title to the list of keywords
  803.       if (htmlIndex)
  804.       {
  805.         OutputCurrentSectionToString(wxTex2RTFBuffer);
  806.         AddKeyWordForTopic(topicName, wxTex2RTFBuffer, currentFileName);
  807.       }
  808.     }
  809.     break;
  810.   }
  811.   case ltSUBSECTION:
  812.   case ltSUBSECTIONSTAR:
  813.   case ltMEMBERSECTION:
  814.   case ltFUNCTIONSECTION:
  815.   {
  816.     if (!start)
  817.     {
  818.       if (!Sections)
  819.       {
  820.         OnError("You cannot have a subsection before a section!");
  821.       }
  822.       else
  823.       {
  824.           subsubsectionNo = 0;
  825.  
  826.           if (macroId != ltSUBSECTIONSTAR)
  827.             subsectionNo ++;
  828.  
  829.           if ( combineSubSections && !subsectionStarted )
  830.           {
  831.             // Read old .con file in at this point
  832.             char buf[256];
  833.             strcpy(buf, CurrentSectionFile);
  834.             wxStripExtension(buf);
  835.             strcat(buf, ".con");
  836.             FILE *fd = fopen(buf, "r");
  837.             if ( fd )
  838.             {
  839.                 int ch = getc(fd);
  840.                 while (ch != EOF)
  841.                 {
  842.                     putc(ch, Sections);
  843.                     ch = getc(fd);
  844.                 }
  845.                 fclose(fd);
  846.             }
  847.             fprintf(Sections, "<P>\n");
  848.  
  849.             // Close old file, create a new file for the sub(sub)section contents entries
  850.             ReopenSectionContentsFile();
  851.           }
  852.  
  853.           startedSections = TRUE;
  854.           subsectionStarted = TRUE;
  855.  
  856.           char *topicName = FindTopicName(GetNextChunk());
  857.  
  858.           if ( !combineSubSections )
  859.           {
  860.             SetCurrentOutput(NULL);
  861.             ReopenFile(&Subsections, &SubsectionsName);
  862.             AddTexRef(topicName, SubsectionsName, SubsectionNameString);
  863.             SetCurrentSubsectionName(topicName, SubsectionsName);
  864.             if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SubsectionsName);
  865.             SetCurrentOutput(Subsections);
  866.  
  867.         HTMLHead();
  868.             TexOutput("<title>");
  869.             OutputCurrentSection();
  870.             TexOutput("</title></head>\n");
  871.             OutputBodyStart();
  872.  
  873.             fprintf(Subsections, "<A NAME=\"%s\"></A>", topicName);
  874.             AddBrowseButtons(CurrentSectionName, CurrentSectionFile, // Up
  875.                            lastTopic, lastFileName,  // Last topic
  876.                            topicName, SubsectionsName); // This topic
  877.  
  878.             SetCurrentOutputs(Sections, Subsections);
  879.             fprintf(Sections, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsectionsName), topicName);
  880.  
  881.             fprintf(Subsections, "\n<H3>");
  882.             OutputCurrentSection();
  883.             fprintf(Sections, "</B></A><BR>\n");
  884.             fprintf(Subsections, "</H3>\n");
  885.  
  886.             SetCurrentOutput(Subsections);
  887.           }
  888.           else
  889.           {
  890.             AddTexRef(topicName, SectionsName, SubsectionNameString);
  891.             SetCurrentSubsectionName(topicName, SectionsName);
  892.  
  893. //            if ( subsectionNo != 0 )
  894.             fprintf(Sections, "\n<HR>\n");
  895.  
  896.             // We're putting everything into the section file
  897.             fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
  898.             fprintf(Sections, "\n<H3>");
  899.             OutputCurrentSection();
  900.             fprintf(Sections, "</H3>\n");
  901.  
  902.             SetCurrentOutput(SectionContentsFD);
  903.             fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName);
  904.             OutputCurrentSection();
  905.             TexOutput("</A><BR>\n");
  906.  
  907.             if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SectionsName);
  908.             SetCurrentOutput(Sections);
  909.           }
  910.           // Add this section title to the list of keywords
  911.           if (htmlIndex)
  912.           {
  913.             OutputCurrentSectionToString(wxTex2RTFBuffer);
  914.             AddKeyWordForTopic(topicName, wxTex2RTFBuffer, currentFileName);
  915.           }
  916.  
  917.       }
  918.     }
  919.     break;
  920.   }
  921.   case ltSUBSUBSECTION:
  922.   case ltSUBSUBSECTIONSTAR:
  923.   {
  924.     if (!start)
  925.     {
  926.       if (!Subsections && !combineSubSections)
  927.       {
  928.         OnError("You cannot have a subsubsection before a subsection!");
  929.       }
  930.       else
  931.       {
  932.         if (macroId != ltSUBSUBSECTIONSTAR)
  933.           subsubsectionNo ++;
  934.  
  935.         startedSections = TRUE;
  936.  
  937.         char *topicName = FindTopicName(GetNextChunk());
  938.  
  939.         if ( !combineSubSections )
  940.         {
  941.             SetCurrentOutput(NULL);
  942.             ReopenFile(&Subsubsections, &SubsubsectionsName);
  943.             AddTexRef(topicName, SubsubsectionsName, SubsubsectionNameString);
  944.             SetCurrentSubsubsectionName(topicName, SubsubsectionsName);
  945.             if (htmlWorkshopFiles) HTMLWorkshopAddToContents(3, topicName, SubsubsectionsName);
  946.  
  947.             SetCurrentOutput(Subsubsections);
  948.         HTMLHead();
  949.             TexOutput("<title>");
  950.             OutputCurrentSection();
  951.             TexOutput("</title></head>\n");
  952.             OutputBodyStart();
  953.  
  954.             fprintf(Subsubsections, "<A NAME=\"%s\"></A>", topicName);
  955.  
  956.             AddBrowseButtons(CurrentSubsectionName, CurrentSubsectionFile, // Up
  957.                          lastTopic, lastFileName,  // Last topic
  958.                          topicName, SubsubsectionsName); // This topic
  959.  
  960.             SetCurrentOutputs(Subsections, Subsubsections);
  961.             fprintf(Subsections, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsubsectionsName), topicName);
  962.  
  963.             fprintf(Subsubsections, "\n<H3>");
  964.             OutputCurrentSection();
  965.             fprintf(Subsections, "</B></A><BR>\n");
  966.             fprintf(Subsubsections, "</H3>\n");
  967.         }
  968.         else
  969.         {
  970.             AddTexRef(topicName, SectionsName, SubsubsectionNameString);
  971.             SetCurrentSubsectionName(topicName, SectionsName);
  972.             fprintf(Sections, "\n<HR>\n");
  973.  
  974.             // We're putting everything into the section file
  975.             fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
  976.             fprintf(Sections, "\n<H3>");
  977.             OutputCurrentSection();
  978.             fprintf(Sections, "</H3>\n");
  979. /* TODO: where do we put subsubsection contents entry - indented, with subsection entries?
  980.             SetCurrentOutput(SectionContentsFD);
  981.             fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName);
  982.             OutputCurrentSection();
  983.             TexOutput("</A><BR>");
  984. */
  985.             if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SectionsName);
  986.             SetCurrentOutput(Sections);
  987.         }
  988.  
  989.         // Add this section title to the list of keywords
  990.         if (htmlIndex)
  991.         {
  992.           OutputCurrentSectionToString(wxTex2RTFBuffer);
  993.           AddKeyWordForTopic(topicName, wxTex2RTFBuffer, currentFileName);
  994.         }
  995.       }
  996.     }
  997.     break;
  998.   }
  999.   case ltFUNC:
  1000.   case ltPFUNC:
  1001.   {
  1002.     if ( !combineSubSections )
  1003.         SetCurrentOutput(Subsections);
  1004.     else
  1005.         SetCurrentOutput(Sections);
  1006.     if (start)
  1007.     {
  1008.     }
  1009.     else
  1010.     {
  1011.     }
  1012.     break;
  1013.   }
  1014.   case ltCLIPSFUNC:
  1015.   {
  1016.     if ( !combineSubSections )
  1017.         SetCurrentOutput(Subsections);
  1018.     else
  1019.         SetCurrentOutput(Sections);
  1020.     if (start)
  1021.     {
  1022.     }
  1023.     else
  1024.     {
  1025.     }
  1026.     break;
  1027.   }
  1028.   case ltMEMBER:
  1029.   {
  1030.     if ( !combineSubSections )
  1031.         SetCurrentOutput(Subsections);
  1032.     else
  1033.         SetCurrentOutput(Sections);
  1034.     if (start)
  1035.     {
  1036.     }
  1037.     else
  1038.     {
  1039.     }
  1040.     break;
  1041.   }
  1042.   case ltVOID:
  1043. //    if (start)
  1044. //      TexOutput("<B>void</B>");
  1045.     break;
  1046.   case ltHARDY:
  1047.     if (start)
  1048.       TexOutput("HARDY");
  1049.     break;
  1050.   case ltWXCLIPS:
  1051.     if (start)
  1052.       TexOutput("wxCLIPS");
  1053.     break;
  1054.   case ltAMPERSAND:
  1055.     if (start)
  1056.       TexOutput("&");
  1057.     break;
  1058.   case ltSPECIALAMPERSAND:
  1059.   {
  1060.     if (start)
  1061.     {
  1062.       if (inTabular)
  1063.       {
  1064.         // End cell, start cell
  1065.  
  1066.         TexOutput("</FONT></TD>");
  1067.  
  1068.         // Start new row and cell, setting alignment for the first cell.
  1069.         if (currentColumn < noColumns)
  1070.           currentColumn ++;
  1071.  
  1072.         char buf[100];
  1073.         if (TableData[currentColumn].justification == 'c')
  1074.           sprintf(buf, "\n<TD ALIGN=CENTER>");
  1075.         else if (TableData[currentColumn].justification == 'r')
  1076.           sprintf(buf, "\n<TD ALIGN=RIGHT>");
  1077.         else if (TableData[currentColumn].absWidth)
  1078.         {
  1079.           // Convert from points * 20 into pixels.
  1080.           int points = TableData[currentColumn].width / 20;
  1081.  
  1082.           // Say the display is 100 DPI (dots/pixels per inch).
  1083.           // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots.
  1084.           int pixels = (int)(points * 100.0 / 72.0);
  1085.           sprintf(buf, "<TD ALIGN=CENTER WIDTH=%d>", pixels);
  1086.         }
  1087.         else
  1088.           sprintf(buf, "\n<TD ALIGN=LEFT>");
  1089.         TexOutput(buf);
  1090.         OutputFont();
  1091.       }
  1092.       else
  1093.         TexOutput("&");
  1094.     }
  1095.     break;
  1096.   }
  1097.   case ltBACKSLASHCHAR:
  1098.   {
  1099.     if (start)
  1100.     {
  1101.       if (inTabular)
  1102.       {
  1103.         // End row. In fact, tables without use of \row or \ruledrow isn't supported for
  1104.         // HTML: the syntax is too different (e.g. how do we know where to put the first </TH>
  1105.         // if we've ended the last row?). So normally you wouldn't use \\ to end a row.
  1106.         TexOutput("</TR>\n");
  1107.       }
  1108.       else
  1109.         TexOutput("<BR>\n");
  1110.     }
  1111.     break;
  1112.   }
  1113.   case ltROW:
  1114.   case ltRULEDROW:
  1115.   {
  1116.     if (start)
  1117.     {
  1118.       currentColumn = 0;
  1119.  
  1120.       // Start new row and cell, setting alignment for the first cell.
  1121.       char buf[100];
  1122.       if (TableData[currentColumn].justification == 'c')
  1123.         sprintf(buf, "<TR>\n<TD ALIGN=CENTER>");
  1124.       else if (TableData[currentColumn].justification == 'r')
  1125.         sprintf(buf, "<TR>\n<TD ALIGN=RIGHT>");
  1126.       else if (TableData[currentColumn].absWidth)
  1127.       {
  1128.         // Convert from points * 20 into pixels.
  1129.         int points = TableData[currentColumn].width / 20;
  1130.  
  1131.         // Say the display is 100 DPI (dots/pixels per inch).
  1132.         // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots.
  1133.         int pixels = (int)(points * 100.0 / 72.0);
  1134.         sprintf(buf, "<TR>\n<TD ALIGN=CENTER WIDTH=%d>", pixels);
  1135.       }
  1136.       else
  1137.         sprintf(buf, "<TR>\n<TD ALIGN=LEFT>");
  1138.       TexOutput(buf);
  1139.       OutputFont();
  1140.     }
  1141.     else
  1142.     {
  1143.       // End cell and row
  1144.       // Start new row and cell
  1145.       TexOutput("</FONT></TD>\n</TR>\n");
  1146.     }
  1147.     break;
  1148.   }
  1149.   // HTML-only: break until the end of the picture (both margins are clear).
  1150.   case ltBRCLEAR:
  1151.   {
  1152.     if (start)
  1153.       TexOutput("<BR CLEAR=ALL>");
  1154.     break;
  1155.   }
  1156.   case ltRTFSP:  // Explicit space, RTF only
  1157.     break;
  1158.   case ltSPECIALTILDE:
  1159.   {
  1160.     if (start)
  1161.     {
  1162.       if (inVerbatim)
  1163.         TexOutput("~");
  1164.       else
  1165.         TexOutput(" ");
  1166.     }
  1167.     break;
  1168.   }
  1169.   case ltINDENTED :
  1170.   {
  1171.     if ( start )
  1172.         TexOutput("<UL><UL>\n");
  1173.     else
  1174.         TexOutput("</UL></UL>\n");
  1175.     break;
  1176.   }
  1177.   case ltITEMIZE:
  1178.   case ltENUMERATE:
  1179.   case ltDESCRIPTION:
  1180. //  case ltTWOCOLLIST:
  1181.   {
  1182.     if (start)
  1183.     {
  1184.       indentLevel ++;
  1185.  
  1186.       int listType;
  1187.       if (macroId == ltENUMERATE)
  1188.         listType = LATEX_ENUMERATE;
  1189.       else if (macroId == ltITEMIZE)
  1190.         listType = LATEX_ITEMIZE;
  1191.       else
  1192.         listType = LATEX_DESCRIPTION;
  1193.  
  1194.       itemizeStack.Insert(new ItemizeStruc(listType));
  1195.       switch (listType)
  1196.       {
  1197.         case LATEX_ITEMIZE:
  1198.           TexOutput("<UL>\n");
  1199.           break;
  1200.         case LATEX_ENUMERATE:
  1201.           TexOutput("<OL>\n");
  1202.           break;
  1203.         case LATEX_DESCRIPTION:
  1204.         default:
  1205.           TexOutput("<DL>\n");
  1206.           break;
  1207.       }
  1208.     }
  1209.     else
  1210.     {
  1211.       indentLevel --;
  1212.       if (itemizeStack.First())
  1213.       {
  1214.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  1215.         switch (struc->listType)
  1216.         {
  1217.           case LATEX_ITEMIZE:
  1218.             TexOutput("</UL>\n");
  1219.             break;
  1220.           case LATEX_ENUMERATE:
  1221.             TexOutput("</OL>\n");
  1222.             break;
  1223.           case LATEX_DESCRIPTION:
  1224.           default:
  1225.             TexOutput("</DL>\n");
  1226.             break;
  1227.         }
  1228.  
  1229.         delete struc;
  1230.         delete itemizeStack.First();
  1231.       }
  1232.     }
  1233.     break;
  1234.   }
  1235.   case ltTWOCOLLIST :
  1236.   {
  1237.     if ( start )
  1238.         TexOutput("\n<TABLE>\n");
  1239.     else {
  1240.         TexOutput("\n</TABLE>\n");
  1241.     // DHS 
  1242.         TwoColWidthA = -1;
  1243.         TwoColWidthB = -1;
  1244.     }
  1245.     break;
  1246.   }
  1247.   case ltPAR:
  1248.   {
  1249.     if (start)
  1250.       TexOutput("<P>\n");
  1251.     break;
  1252.   }
  1253. /* For footnotes we need to output the text at the bottom of the page and
  1254.  * insert a reference to it. Is it worth the trouble...
  1255.   case ltFOOTNOTE:
  1256.   case ltFOOTNOTEPOPUP:
  1257.   {
  1258.     if (start)
  1259.     {
  1260.       TexOutput("<FN>);
  1261.     }
  1262.     else TexOutput("</FN>");
  1263.     break;
  1264.   }
  1265. */
  1266.   case ltVERB:
  1267.   {
  1268.     if (start)
  1269.       TexOutput("<TT>");
  1270.     else TexOutput("</TT>");
  1271.     break;
  1272.   }
  1273.   case ltVERBATIM:
  1274.   {
  1275.     if (start)
  1276.     {
  1277.       char buf[100];
  1278.       sprintf(buf, "<PRE>\n");
  1279.       TexOutput(buf);
  1280.     }
  1281.     else TexOutput("</PRE>\n");
  1282.     break;
  1283.   }
  1284.   case ltCENTERLINE:
  1285.   case ltCENTER:
  1286.   {
  1287.     if (start)
  1288.     {
  1289.       TexOutput("<CENTER>");
  1290.     }
  1291.     else TexOutput("</CENTER>");
  1292.     break;
  1293.   }
  1294.   case ltFLUSHLEFT:
  1295.   {
  1296. /*
  1297.     if (start)
  1298.     {
  1299.       TexOutput("{\\ql ");
  1300.     }
  1301.     else TexOutput("}\\par\\pard\n");
  1302. */
  1303.     break;
  1304.   }
  1305.   case ltFLUSHRIGHT:
  1306.   {
  1307. /*
  1308.     if (start)
  1309.     {
  1310.       TexOutput("{\\qr ");
  1311.     }
  1312.     else TexOutput("}\\par\\pard\n");
  1313. */
  1314.     break;
  1315.   }
  1316.   case ltSMALL:
  1317.   {
  1318.     if (start)
  1319.     {
  1320.       // Netscape extension
  1321.       TexOutput("<FONT SIZE=2>");
  1322.     }
  1323.     else TexOutput("</FONT>");
  1324.     break;
  1325.   }
  1326.   case ltTINY:
  1327.   {
  1328.     if (start)
  1329.     {
  1330.       // Netscape extension
  1331.       TexOutput("<FONT SIZE=1>");
  1332.     }
  1333.     else TexOutput("</FONT>");
  1334.     break;
  1335.   }
  1336.   case ltNORMALSIZE:
  1337.   {
  1338.     if (start)
  1339.     {
  1340.       // Netscape extension
  1341.       TexOutput("<FONT SIZE=3>");
  1342.     }
  1343.     else TexOutput("</FONT>");
  1344.     break;
  1345.   }
  1346.   case ltlarge:
  1347.   {
  1348.     if (start)
  1349.     {
  1350.       // Netscape extension
  1351.       TexOutput("<FONT SIZE=4>");
  1352.     }
  1353.     else TexOutput("</FONT>");
  1354.     break;
  1355.   }
  1356.   case ltLarge:
  1357.   {
  1358.     if (start)
  1359.     {
  1360.       // Netscape extension
  1361.       TexOutput("<FONT SIZE=5>");
  1362.     }
  1363.     else TexOutput("</FONT>");
  1364.     break;
  1365.   }
  1366.   case ltLARGE:
  1367.   {
  1368.     if (start)
  1369.     {
  1370.       // Netscape extension
  1371.       TexOutput("<FONT SIZE=6>");
  1372.     }
  1373.     else TexOutput("</FONT>");
  1374.     break;
  1375.   }
  1376.   case ltBFSERIES:
  1377.   case ltTEXTBF:
  1378.   case ltBF:
  1379.   {
  1380.     if (start)
  1381.     {
  1382.       TexOutput("<B>");
  1383.     }
  1384.     else TexOutput("</B>");
  1385.     break;
  1386.   }
  1387.   case ltITSHAPE:
  1388.   case ltTEXTIT:
  1389.   case ltIT:
  1390.   {
  1391.     if (start)
  1392.     {
  1393.       TexOutput("<I>");
  1394.     }
  1395.     else TexOutput("</I>");
  1396.     break;
  1397.   }
  1398.   case ltEMPH:
  1399.   case ltEM:
  1400.   {
  1401.     if (start)
  1402.     {
  1403.       TexOutput("<EM>");
  1404.     }
  1405.     else TexOutput("</EM>");
  1406.     break;
  1407.   }
  1408.   case ltUNDERLINE:
  1409.   {
  1410.     if (start)
  1411.     {
  1412.       TexOutput("<UL>");
  1413.     }
  1414.     else TexOutput("</UL>");
  1415.     break;
  1416.   }
  1417.   case ltTTFAMILY:
  1418.   case ltTEXTTT:
  1419.   case ltTT:
  1420.   {
  1421.     if (start)
  1422.     {
  1423.       TexOutput("<TT>");
  1424.     }
  1425.     else TexOutput("</TT>");
  1426.     break;
  1427.   }
  1428.   case ltCOPYRIGHT:
  1429.   {
  1430.     if (start)
  1431.       TexOutput("©", TRUE);
  1432.     break;
  1433.   }
  1434.   case ltREGISTERED:
  1435.   {
  1436.     if (start)
  1437.       TexOutput("®", TRUE);
  1438.     break;
  1439.   }
  1440.   // Arrows
  1441.   case ltLEFTARROW:
  1442.   {
  1443.     if (start) TexOutput("<--");
  1444.     break;
  1445.   }
  1446.   case ltLEFTARROW2:
  1447.   {
  1448.     if (start) TexOutput("<==");
  1449.     break;
  1450.   }
  1451.   case ltRIGHTARROW:
  1452.   {
  1453.       if (start) TexOutput("-->");
  1454.       break;
  1455.   }
  1456.   case ltRIGHTARROW2:
  1457.   {
  1458.     if (start) TexOutput("==>");
  1459.     break;
  1460.   }
  1461.   case ltLEFTRIGHTARROW:
  1462.   {
  1463.     if (start) TexOutput("<-->");
  1464.     break;
  1465.   }
  1466.   case ltLEFTRIGHTARROW2:
  1467.   {
  1468.     if (start) TexOutput("<==>");
  1469.     break;
  1470.   }
  1471. /*
  1472.   case ltSC:
  1473.   {
  1474.     break;
  1475.   }
  1476. */
  1477.   case ltITEM:
  1478.   {
  1479.     if (!start)
  1480.     {
  1481.       wxNode *node = itemizeStack.First();
  1482.       if (node)
  1483.       {
  1484.         ItemizeStruc *struc = (ItemizeStruc *)node->Data();
  1485.         struc->currentItem += 1;
  1486.         if (struc->listType == LATEX_DESCRIPTION)
  1487.         {
  1488.           if (descriptionItemArg)
  1489.           {
  1490.             TexOutput("<DT> ");
  1491.             TraverseChildrenFromChunk(descriptionItemArg);
  1492.             TexOutput("\n");
  1493.             descriptionItemArg = NULL;
  1494.           }
  1495.           TexOutput("<DD>");
  1496.         }
  1497.         else
  1498.           TexOutput("<LI>");
  1499.       }
  1500.     }
  1501.     break;
  1502.   }
  1503.   case ltMAKETITLE:
  1504.   {
  1505.     if (start && DocumentTitle && DocumentAuthor)
  1506.     {
  1507.       // Add a special label for the contents page.
  1508. //      TexOutput("<CENTER>\n");
  1509.       TexOutput("<A NAME=\"contents\">");
  1510.       TexOutput("<H2 ALIGN=CENTER>\n");
  1511.       TraverseChildrenFromChunk(DocumentTitle);
  1512.       TexOutput("</H2>");
  1513.       TexOutput("<P>");
  1514.       TexOutput("</A>\n");
  1515.       TexOutput("<P>\n\n");
  1516.       TexOutput("<H3 ALIGN=CENTER>");
  1517.       TraverseChildrenFromChunk(DocumentAuthor);
  1518.       TexOutput("</H3><P>\n\n");
  1519.       if (DocumentDate)
  1520.       {
  1521.         TexOutput("<H3 ALIGN=CENTER>");
  1522.         TraverseChildrenFromChunk(DocumentDate);
  1523.         TexOutput("</H3><P>\n\n");
  1524.       }
  1525. //      TexOutput("\n</CENTER>\n");
  1526.       TexOutput("\n<P><HR><P>\n");
  1527.  
  1528. /*
  1529.       // Now do optional frame contents page
  1530.       if (htmlFrameContents && FrameContents)
  1531.       {
  1532.         SetCurrentOutput(FrameContents);
  1533.  
  1534.         // Add a special label for the contents page.
  1535.         TexOutput("<CENTER>\n");
  1536.         TexOutput("<H3>\n");
  1537.         TraverseChildrenFromChunk(DocumentTitle);
  1538.         TexOutput("</H3>");
  1539.         TexOutput("<P>");
  1540.         TexOutput("</A>\n");
  1541.         TexOutput("<P>\n\n");
  1542.         TexOutput("<H3>");
  1543.         TraverseChildrenFromChunk(DocumentAuthor);
  1544.         TexOutput("</H3><P>\n\n");
  1545.         if (DocumentDate)
  1546.         {
  1547.           TexOutput("<H4>");
  1548.           TraverseChildrenFromChunk(DocumentDate);
  1549.           TexOutput("</H4><P>\n\n");
  1550.         }
  1551.         TexOutput("\n</CENTER>\n");
  1552.         TexOutput("<P><HR><P>\n");
  1553.  
  1554.         SetCurrentOutput(Titlepage);
  1555.       }
  1556. */
  1557.     }
  1558.     break;
  1559.   }
  1560.   case ltHELPREF:
  1561.   case ltHELPREFN:
  1562.   case ltPOPREF:
  1563.   case ltURLREF:
  1564.   {
  1565.     if (start)
  1566.     {
  1567.       helpRefFilename = NULL;
  1568.       helpRefText = NULL;
  1569.     }
  1570.     break;
  1571.   }
  1572.   case ltBIBLIOGRAPHY:
  1573.   {
  1574.     if (start)
  1575.     {
  1576.       DefaultOnMacro(macroId, no_args, start);
  1577.     }
  1578.     else
  1579.     {
  1580.       DefaultOnMacro(macroId, no_args, start);
  1581.       TexOutput("</DL>\n");
  1582.     }
  1583.     break;
  1584.   }
  1585.   case ltHRULE:
  1586.   {
  1587.     if (start)
  1588.     {
  1589.       TexOutput("<HR>\n");
  1590.     }
  1591.     break;
  1592.   }
  1593.   case ltRULE:
  1594.   {
  1595.     if (start)
  1596.     {
  1597.       TexOutput("<HR>\n");
  1598.     }
  1599.     break;
  1600.   }
  1601.   case ltTABLEOFCONTENTS:
  1602.   {
  1603.     if (start)
  1604.     {
  1605.       FILE *fd = fopen(ContentsName, "r");
  1606.       if (fd)
  1607.       {
  1608.         int ch = getc(fd);
  1609.         while (ch != EOF)
  1610.         {
  1611.           putc(ch, Titlepage);
  1612.           ch = getc(fd);
  1613.         }
  1614.         fclose(fd);
  1615.       }
  1616.       else
  1617.       {
  1618.         TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n");
  1619.         OnInform("Run Tex2RTF again to include contents page.");
  1620.       }
  1621.     }
  1622.     break;
  1623.   }
  1624.   case ltLANGLEBRA:
  1625.   {
  1626.     if (start)
  1627.       TexOutput("<");
  1628.     break;
  1629.   }
  1630.   case ltRANGLEBRA:
  1631.   {
  1632.     if (start)
  1633.       TexOutput(">");
  1634.     break;
  1635.   }
  1636.   case ltQUOTE:
  1637.   case ltQUOTATION:
  1638.   {
  1639.     if (start)
  1640.       TexOutput("<BLOCKQUOTE>");
  1641.     else
  1642.       TexOutput("</BLOCKQUOTE>");
  1643.     break;
  1644.   }
  1645.   case ltCAPTION:
  1646.   case ltCAPTIONSTAR:
  1647.   {
  1648.     if (start)
  1649.     {
  1650.       if (inTabular)
  1651.         TexOutput("\n<CAPTION>");
  1652.  
  1653.       char figBuf[40];
  1654.  
  1655.       if ( inFigure )
  1656.       {
  1657.           figureNo ++;
  1658.  
  1659.           if (DocumentStyle != LATEX_ARTICLE)
  1660.             sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo);
  1661.           else
  1662.             sprintf(figBuf, "%s %d: ", FigureNameString, figureNo);
  1663.       }
  1664.       else
  1665.       {
  1666.           tableNo ++;
  1667.  
  1668.           if (DocumentStyle != LATEX_ARTICLE)
  1669.             sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, tableNo);
  1670.           else
  1671.             sprintf(figBuf, "%s %d: ", TableNameString, tableNo);
  1672.       }
  1673.  
  1674.       TexOutput(figBuf);
  1675.     }
  1676.     else
  1677.     {
  1678.       if (inTabular)
  1679.         TexOutput("\n</CAPTION>\n");
  1680.  
  1681.       char *topicName = FindTopicName(GetNextChunk());
  1682.  
  1683.       int n = inFigure ? figureNo : tableNo;
  1684.  
  1685.       AddTexRef(topicName, NULL, NULL,
  1686.            ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
  1687.             ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
  1688.     }
  1689.     break;
  1690.   }
  1691.   case ltSS:
  1692.   {
  1693.     if (start) TexOutput("ß");
  1694.     break;
  1695.   }
  1696.   case ltFIGURE:
  1697.   {
  1698.     if (start) inFigure = TRUE;
  1699.     else inFigure = FALSE;
  1700.     break;
  1701.   }
  1702.   case ltTABLE:
  1703.   {
  1704.     if (start) inTable = TRUE;
  1705.     else inTable = FALSE;
  1706.     break;
  1707.   }
  1708.   default:
  1709.     DefaultOnMacro(macroId, no_args, start);
  1710.     break;
  1711.   }
  1712. }
  1713.  
  1714. // Called on start/end of argument examination
  1715. bool HTMLOnArgument(int macroId, int arg_no, bool start)
  1716. {
  1717.   switch (macroId)
  1718.   {
  1719.   case ltCHAPTER:
  1720.   case ltCHAPTERSTAR:
  1721.   case ltCHAPTERHEADING:
  1722.   case ltSECTION:
  1723.   case ltSECTIONSTAR:
  1724.   case ltSECTIONHEADING:
  1725.   case ltSUBSECTION:
  1726.   case ltSUBSECTIONSTAR:
  1727.   case ltSUBSUBSECTION:
  1728.   case ltSUBSUBSECTIONSTAR:
  1729.   case ltGLOSS:
  1730.   case ltMEMBERSECTION:
  1731.   case ltFUNCTIONSECTION:
  1732.   {
  1733.     if (!start && (arg_no == 1))
  1734.       currentSection = GetArgChunk();
  1735.     return FALSE;
  1736.     break;
  1737.   }
  1738.   case ltFUNC:
  1739.   {
  1740.     if (start && (arg_no == 1))
  1741.       TexOutput("<B>");
  1742.  
  1743.     if (!start && (arg_no == 1))
  1744.       TexOutput("</B> ");
  1745.  
  1746.     if (start && (arg_no == 2))
  1747.     {
  1748.       if (!suppressNameDecoration) TexOutput("<B>");
  1749.       currentMember = GetArgChunk();
  1750.     }
  1751.     if (!start && (arg_no == 2))
  1752.     {
  1753.       if (!suppressNameDecoration) TexOutput("</B>");
  1754.     }
  1755.  
  1756.     if (start && (arg_no == 3))
  1757.       TexOutput("(");
  1758.     if (!start && (arg_no == 3))
  1759.      TexOutput(")");
  1760.    break;
  1761.   }
  1762.   case ltCLIPSFUNC:
  1763.   {
  1764.     if (start && (arg_no == 1))
  1765.       TexOutput("<B>");
  1766.     if (!start && (arg_no == 1))
  1767.       TexOutput("</B> ");
  1768.  
  1769.     if (start && (arg_no == 2))
  1770.     {
  1771.       if (!suppressNameDecoration) TexOutput("( ");
  1772.       currentMember = GetArgChunk();
  1773.     }
  1774.     if (!start && (arg_no == 2))
  1775.     {
  1776.     }
  1777.  
  1778.     if (!start && (arg_no == 3))
  1779.      TexOutput(")");
  1780.     break;
  1781.   }
  1782.   case ltPFUNC:
  1783.   {
  1784.     if (!start && (arg_no == 1))
  1785.       TexOutput(" ");
  1786.  
  1787.     if (start && (arg_no == 2))
  1788.       TexOutput("(*");
  1789.     if (!start && (arg_no == 2))
  1790.       TexOutput(")");
  1791.  
  1792.     if (start && (arg_no == 2))
  1793.       currentMember = GetArgChunk();
  1794.  
  1795.     if (start && (arg_no == 3))
  1796.       TexOutput("(");
  1797.     if (!start && (arg_no == 3))
  1798.       TexOutput(")");
  1799.     break;
  1800.   }
  1801.   case ltPARAM:
  1802.   {
  1803.     if (start && (arg_no == 1))
  1804.       TexOutput("<B>");
  1805.     if (!start && (arg_no == 1))
  1806.       TexOutput("</B>");
  1807.     if (start && (arg_no == 2))
  1808.     {
  1809.       TexOutput("<I>");
  1810.     }
  1811.     if (!start && (arg_no == 2))
  1812.     {
  1813.       TexOutput("</I>");
  1814.     }
  1815.     break;
  1816.   }
  1817.   case ltCPARAM:
  1818.   {
  1819.     if (start && (arg_no == 1))
  1820.       TexOutput("<B>");
  1821.     if (!start && (arg_no == 1))
  1822.       TexOutput("</B> ");  // This is the difference from param - one space!
  1823.     if (start && (arg_no == 2))
  1824.     {
  1825.       TexOutput("<I>");
  1826.     }
  1827.     if (!start && (arg_no == 2))
  1828.     {
  1829.       TexOutput("</I>");
  1830.     }
  1831.     break;
  1832.   }
  1833.   case ltMEMBER:
  1834.   {
  1835.     if (!start && (arg_no == 1))
  1836.       TexOutput(" ");
  1837.  
  1838.     if (start && (arg_no == 2))
  1839.       currentMember = GetArgChunk();
  1840.     break;
  1841.   }
  1842.   case ltREF:
  1843.   {
  1844.     if (start)
  1845.     {
  1846.       char *sec = NULL;
  1847.  
  1848.       char *refName = GetArgData();
  1849.       if (refName)
  1850.       {
  1851.         TexRef *texRef = FindReference(refName);
  1852.         if (texRef)
  1853.         {
  1854.           sec = texRef->sectionNumber;
  1855.         }
  1856.       }
  1857.       if (sec)
  1858.       {
  1859.         TexOutput(sec);
  1860.       }
  1861.       return FALSE;
  1862.     }
  1863.     break;
  1864.   }
  1865.   case ltURLREF:
  1866.   {
  1867.     if (IsArgOptional())
  1868.       return FALSE;
  1869.     else if ((GetNoArgs() - arg_no) == 1)
  1870.     {
  1871.       if (start)
  1872.         helpRefText = GetArgChunk();
  1873.       return FALSE;
  1874.     }
  1875.     else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  1876.     {
  1877.       if (start)
  1878.       {
  1879.         TexChunk *ref = GetArgChunk();
  1880.         TexOutput("<A HREF=\"");
  1881.         inVerbatim = TRUE;
  1882.         TraverseChildrenFromChunk(ref);
  1883.         inVerbatim = FALSE;
  1884.         TexOutput("\">");
  1885.         if (helpRefText)
  1886.           TraverseChildrenFromChunk(helpRefText);
  1887.         TexOutput("</A>");
  1888.       }
  1889.       return FALSE;
  1890.     }
  1891.     break;
  1892.   }
  1893.   case ltHELPREF:
  1894.   case ltHELPREFN:
  1895.   case ltPOPREF:
  1896.   {
  1897.     if (IsArgOptional())
  1898.     {
  1899.       if (start)
  1900.         helpRefFilename = GetArgChunk();
  1901.       return FALSE;
  1902.     }
  1903.     if ((GetNoArgs() - arg_no) == 1)
  1904.     {
  1905.       if (start)
  1906.         helpRefText = GetArgChunk();
  1907.       return FALSE;
  1908.     }
  1909.     else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  1910.     {
  1911.       if (start)
  1912.       {
  1913.         char *refName = GetArgData();
  1914.         char *refFilename = NULL;
  1915.  
  1916.         if (refName)
  1917.         {
  1918.           TexRef *texRef = FindReference(refName);
  1919.           if (texRef)
  1920.           {
  1921.             if (texRef->refFile && strcmp(texRef->refFile, "??") != 0)
  1922.               refFilename = texRef->refFile;
  1923.  
  1924.             TexOutput("<A HREF=\"");
  1925.             // If a filename is supplied, use it, otherwise try to
  1926.             // use the filename associated with the reference (from this document).
  1927.             if (helpRefFilename)
  1928.             {
  1929.               TraverseChildrenFromChunk(helpRefFilename);
  1930.               TexOutput("#");
  1931.             }
  1932.             else if (refFilename)
  1933.             {
  1934.               TexOutput(ConvertCase(refFilename));
  1935.               TexOutput("#");
  1936.             }
  1937.             TexOutput(refName);
  1938.             TexOutput("\">");
  1939.             if (helpRefText)
  1940.               TraverseChildrenFromChunk(helpRefText);
  1941.             TexOutput("</A>");
  1942.           }
  1943.           else
  1944.           {
  1945.             if (helpRefText)
  1946.               TraverseChildrenFromChunk(helpRefText);
  1947.             if (!ignoreBadRefs)
  1948.               TexOutput(" (REF NOT FOUND)");
  1949.             wxString errBuf;
  1950.             errBuf.Printf("Warning: unresolved reference '%s'", refName);
  1951.             OnInform((char *)errBuf.c_str());
  1952.           }
  1953.         }
  1954.         else TexOutput("??");
  1955.       }
  1956.       return FALSE;
  1957.     }
  1958.     break;
  1959.   }
  1960.   case ltIMAGE:
  1961.   case ltIMAGEL:
  1962.   case ltIMAGER:
  1963.   case ltPSBOXTO:
  1964.   {
  1965.     if (arg_no == 2)
  1966.     {
  1967.       if (start)
  1968.       {
  1969.         char *alignment = "";
  1970.         if (macroId == ltIMAGEL)
  1971.           alignment = " align=left";
  1972.         else if  (macroId == ltIMAGER)
  1973.           alignment = " align=right";
  1974.  
  1975.         // Try to find an XBM or GIF image first.
  1976.         char *filename = copystring(GetArgData());
  1977.         char buf[500];
  1978.  
  1979.         strcpy(buf, filename);
  1980.         StripExtension(buf);
  1981.         strcat(buf, ".xbm");
  1982.         wxString f = TexPathList.FindValidPath(buf);
  1983.  
  1984.         if (f == "") // Try for a GIF instead
  1985.         {
  1986.           strcpy(buf, filename);
  1987.           StripExtension(buf);
  1988.           strcat(buf, ".gif");
  1989.           f = TexPathList.FindValidPath(buf);
  1990.         }
  1991.  
  1992.         if (f == "") // Try for a JPEG instead
  1993.         {
  1994.           strcpy(buf, filename);
  1995.           StripExtension(buf);
  1996.           strcat(buf, ".jpg");
  1997.           f = TexPathList.FindValidPath(buf);
  1998.         }
  1999.  
  2000.         if (f == "") // Try for a PNG instead
  2001.         {
  2002.           strcpy(buf, filename);
  2003.           StripExtension(buf);
  2004.           strcat(buf, ".png");
  2005.           f = TexPathList.FindValidPath(buf);
  2006.         }
  2007.  
  2008.         if (f != "")
  2009.         {
  2010.           char *inlineFilename = copystring(f);
  2011. #if 0
  2012.           char *originalFilename = TexPathList.FindValidPath(filename);
  2013.           // If we have found the existing filename, make the inline
  2014.           // image point to the original file (could be PS, for example)
  2015.           if (originalFilename && (strcmp(inlineFilename, originalFilename) != 0))
  2016.       {
  2017.             TexOutput("<A HREF=\"");
  2018.             TexOutput(ConvertCase(originalFilename));
  2019.             TexOutput("\">");
  2020.             TexOutput("<img src=\"");
  2021.             TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename)));
  2022.             TexOutput("\""); TexOutput(alignment); TexOutput("></A>");
  2023.       }
  2024.           else
  2025. #endif
  2026.       {
  2027.             TexOutput("<img src=\"");
  2028.             TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename)));
  2029.             TexOutput("\""); TexOutput(alignment); TexOutput(">");
  2030.             delete[] inlineFilename;
  2031.       }
  2032.         }
  2033.         else
  2034.         {
  2035.           // Last resort - a link to a PS file.
  2036.           TexOutput("<A HREF=\"");
  2037.           TexOutput(ConvertCase(wxFileNameFromPath(filename)));
  2038.           TexOutput("\">Picture</A>\n");
  2039.           sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename);
  2040.           OnInform(buf);
  2041.         }
  2042.       }
  2043.     }
  2044.     return FALSE;
  2045.     break;
  2046.   }
  2047.   // First arg is PSBOX spec (ignored), second is image file, third is map name.
  2048.   case ltIMAGEMAP:
  2049.   {
  2050.     static char *imageFile = NULL;
  2051.     if (start && (arg_no == 2))
  2052.     {
  2053.       // Try to find an XBM or GIF image first.
  2054.       char *filename = copystring(GetArgData());
  2055.       char buf[500];
  2056.  
  2057.       strcpy(buf, filename);
  2058.       StripExtension(buf);
  2059.       strcat(buf, ".xbm");
  2060.       wxString f = TexPathList.FindValidPath(buf);
  2061.  
  2062.       if (f == "") // Try for a GIF instead
  2063.       {
  2064.         strcpy(buf, filename);
  2065.         StripExtension(buf);
  2066.         strcat(buf, ".gif");
  2067.         f = TexPathList.FindValidPath(buf);
  2068.       }
  2069.       if (f == "")
  2070.       {
  2071.         char buf[300];
  2072.         sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename);
  2073.         OnInform(buf);
  2074.       }
  2075.       delete[] filename;
  2076.       if (imageFile)
  2077.         delete[] imageFile;
  2078.       imageFile = NULL;
  2079.       if (!f.IsEmpty())
  2080.       {
  2081.         imageFile = copystring(f);
  2082.       }
  2083.     }
  2084.     else if (start && (arg_no == 3))
  2085.     {
  2086.       if (imageFile)
  2087.       {
  2088.         // First, try to find a .shg (segmented hypergraphics file)
  2089.         // that we can convert to a map file
  2090.         char buf[256];
  2091.         strcpy(buf, imageFile);
  2092.         StripExtension(buf);
  2093.         strcat(buf, ".shg");
  2094.         wxString f = TexPathList.FindValidPath(buf);
  2095.  
  2096.         if (f != "")
  2097.         {
  2098.           // The default HTML file to go to is THIS file (so a no-op)
  2099.           SHGToMap((char*) (const char*) f, currentFileName);
  2100.         }
  2101.  
  2102.         char *mapName = GetArgData();
  2103.         TexOutput("<A HREF=\"/cgi-bin/imagemap/");
  2104.         if (mapName)
  2105.           TexOutput(mapName);
  2106.         else
  2107.           TexOutput("unknown");
  2108.         TexOutput("\">");
  2109.         TexOutput("<img src=\"");
  2110.         TexOutput(ConvertCase(wxFileNameFromPath(imageFile)));
  2111.         TexOutput("\" ISMAP></A><P>");
  2112.         delete[] imageFile;
  2113.         imageFile = NULL;
  2114.       }
  2115.     }
  2116.     return FALSE;
  2117.     break;
  2118.   }
  2119.   case ltINDENTED :
  2120.   {
  2121.     if ( arg_no == 1 )
  2122.         return FALSE;
  2123.     else
  2124.     {
  2125.         return TRUE;
  2126.     }
  2127.   }
  2128.   case ltITEM:
  2129.   {
  2130.     if (start)
  2131.     {
  2132.       descriptionItemArg = GetArgChunk();
  2133.       return FALSE;
  2134.     }
  2135.     return TRUE;
  2136.   }
  2137.   case ltTWOCOLITEM:
  2138.   case ltTWOCOLITEMRULED:
  2139.   {
  2140. /*
  2141.     if (start && (arg_no == 1))
  2142.       TexOutput("\n<DT> ");
  2143.     if (start && (arg_no == 2))
  2144.       TexOutput("<DD> ");
  2145. */
  2146.     if (arg_no == 1)
  2147.     {
  2148.       if ( start ) {
  2149.         // DHS
  2150.     if (TwoColWidthA > -1) {
  2151.           char buf[100];
  2152.           sprintf(buf,"\n<TR><TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthA);
  2153.           TexOutput(buf);
  2154.         } else
  2155.           TexOutput("\n<TR><TD VALIGN=TOP>\n");
  2156.         OutputFont();
  2157.       }  else
  2158.             TexOutput("\n</FONT></TD>\n");
  2159.     }
  2160.     if (arg_no == 2)
  2161.     {
  2162.       // DHS
  2163.       if ( start ) {
  2164.     if (TwoColWidthB > -1) {
  2165.           char buf[100];
  2166.           sprintf(buf,"\n<TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthB);
  2167.           TexOutput(buf);
  2168.         } else 
  2169.            TexOutput("\n<TD VALIGN=TOP>\n");
  2170.         OutputFont();
  2171.       }  else
  2172.            TexOutput("\n</FONT></TD></TR>\n");
  2173.     }
  2174.     return TRUE;
  2175.     break;
  2176.   }
  2177.   case ltNUMBEREDBIBITEM:
  2178.   {
  2179.     if (arg_no == 1 && start)
  2180.     {
  2181.       TexOutput("\n<DT> ");
  2182.     }
  2183.     if (arg_no == 2 && !start)
  2184.       TexOutput("<P>\n");
  2185.     break;
  2186.   }
  2187.   case ltBIBITEM:
  2188.   {
  2189.     char buf[100];
  2190.     if (arg_no == 1 && start)
  2191.     {
  2192.       char *citeKey = GetArgData();
  2193.       TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
  2194.       if (ref)
  2195.       {
  2196.         if (ref->sectionNumber) delete[] ref->sectionNumber;
  2197.         sprintf(buf, "[%d]", citeCount);
  2198.         ref->sectionNumber = copystring(buf);
  2199.       }
  2200.  
  2201.       sprintf(buf, "\n<DT> [%d] ", citeCount);
  2202.       TexOutput(buf);
  2203.       citeCount ++;
  2204.       return FALSE;
  2205.     }
  2206.     if (arg_no == 2 && !start)
  2207.       TexOutput("<P>\n");
  2208.     return TRUE;
  2209.     break;
  2210.   }
  2211.   case ltMARGINPAR:
  2212.   case ltMARGINPARODD:
  2213.   case ltMARGINPAREVEN:
  2214.   case ltNORMALBOX:
  2215.   case ltNORMALBOXD:
  2216.   {
  2217.     if (start)
  2218.     {
  2219.       TexOutput("<HR>\n");
  2220.       return TRUE;
  2221.     }
  2222.     else
  2223.       TexOutput("<HR><P>\n");
  2224.     break;
  2225.   }
  2226.   // DHS
  2227.   case ltTWOCOLWIDTHA:
  2228.   {
  2229.     if (start)
  2230.     {
  2231.       char *val = GetArgData();
  2232.       float points = ParseUnitArgument(val);
  2233.       TwoColWidthA = (int)((points * 100.0) / 72.0);
  2234.     }
  2235.     return FALSE;
  2236.     break;
  2237.   }
  2238.   // DHS
  2239.   case ltTWOCOLWIDTHB:
  2240.   {
  2241.     if (start)
  2242.     {
  2243.       char *val = GetArgData();
  2244.       float points = ParseUnitArgument(val);
  2245.       TwoColWidthB = (int)((points * 100.0) / 72.0);
  2246.     }
  2247.     return FALSE;
  2248.     break;
  2249.   }
  2250.   /*
  2251.    * Accents
  2252.    *
  2253.    */
  2254.   case ltACCENT_GRAVE:
  2255.   {
  2256.     if (start)
  2257.     {
  2258.       char *val = GetArgData();
  2259.       if (val)
  2260.       {
  2261.         switch (val[0])
  2262.         {
  2263.           case 'a':
  2264.            TexOutput("à");
  2265.            break;
  2266.           case 'e':
  2267.            TexOutput("è");
  2268.            break;
  2269.           case 'i':
  2270.            TexOutput("ì");
  2271.            break;
  2272.           case 'o':
  2273.            TexOutput("ò");
  2274.            break;
  2275.           case 'u':
  2276.            TexOutput("ù");
  2277.            break;
  2278.           case 'A':
  2279.            TexOutput("À");
  2280.            break;
  2281.           case 'E':
  2282.            TexOutput("È");
  2283.            break;
  2284.           case 'I':
  2285.            TexOutput("Ì");
  2286.            break;
  2287.           case 'O':
  2288.            TexOutput("Ò");
  2289.            break;
  2290.           case 'U':
  2291.            TexOutput("Ì");
  2292.            break;
  2293.           default:
  2294.            break;
  2295.         }
  2296.       }
  2297.     }
  2298.     return FALSE;
  2299.     break;
  2300.   }
  2301.   case ltACCENT_ACUTE:
  2302.   {
  2303.     if (start)
  2304.     {
  2305.       char *val = GetArgData();
  2306.       if (val)
  2307.       {
  2308.         switch (val[0])
  2309.         {
  2310.           case 'a':
  2311.            TexOutput("á");
  2312.            break;
  2313.           case 'e':
  2314.            TexOutput("é");
  2315.            break;
  2316.           case 'i':
  2317.            TexOutput("í");
  2318.            break;
  2319.           case 'o':
  2320.            TexOutput("ó");
  2321.            break;
  2322.           case 'u':
  2323.            TexOutput("ú");
  2324.            break;
  2325.           case 'y':
  2326.            TexOutput("ý");
  2327.            break;
  2328.           case 'A':
  2329.            TexOutput("Á");
  2330.            break;
  2331.           case 'E':
  2332.            TexOutput("É");
  2333.            break;
  2334.           case 'I':
  2335.            TexOutput("Í");
  2336.            break;
  2337.           case 'O':
  2338.            TexOutput("Ó");
  2339.            break;
  2340.           case 'U':
  2341.            TexOutput("Ú");
  2342.            break;
  2343.           case 'Y':
  2344.            TexOutput("Ý");
  2345.            break;
  2346.           default:
  2347.            break;
  2348.         }
  2349.       }
  2350.     }
  2351.     return FALSE;
  2352.     break;
  2353.   }
  2354.   case ltACCENT_CARET:
  2355.   {
  2356.     if (start)
  2357.     {
  2358.       char *val = GetArgData();
  2359.       if (val)
  2360.       {
  2361.         switch (val[0])
  2362.         {
  2363.           case 'a':
  2364.            TexOutput("â");
  2365.            break;
  2366.           case 'e':
  2367.            TexOutput("ê");
  2368.            break;
  2369.           case 'i':
  2370.            TexOutput("î");
  2371.            break;
  2372.           case 'o':
  2373.            TexOutput("ô");
  2374.            break;
  2375.           case 'u':
  2376.            TexOutput("û");
  2377.            break;
  2378.           case 'A':
  2379.            TexOutput("Â");
  2380.            break;
  2381.           case 'E':
  2382.            TexOutput("Ê");
  2383.            break;
  2384.           case 'I':
  2385.            TexOutput("Î");
  2386.            break;
  2387.           case 'O':
  2388.            TexOutput("Ô");
  2389.            break;
  2390.           case 'U':
  2391.            TexOutput("Î");
  2392.            break;
  2393.           default:
  2394.            break;
  2395.         }
  2396.       }
  2397.     }
  2398.     return FALSE;
  2399.     break;
  2400.   }
  2401.   case ltACCENT_TILDE:
  2402.   {
  2403.     if (start)
  2404.     {
  2405.       char *val = GetArgData();
  2406.       if (val)
  2407.       {
  2408.         switch (val[0])
  2409.         {
  2410.           case ' ':
  2411.            TexOutput("~");
  2412.            break;
  2413.           case 'a':
  2414.            TexOutput("ã");
  2415.            break;
  2416.           case 'n':
  2417.            TexOutput("ñ");
  2418.            break;
  2419.           case 'o':
  2420.            TexOutput("õ");
  2421.            break;
  2422.           case 'A':
  2423.            TexOutput("Ã");
  2424.            break;
  2425.           case 'N':
  2426.            TexOutput("Ñ");
  2427.            break;
  2428.           case 'O':
  2429.            TexOutput("Õ");
  2430.            break;
  2431.           default:
  2432.            break;
  2433.         }
  2434.       }
  2435.     }
  2436.     return FALSE;
  2437.     break;
  2438.   }
  2439.   case ltACCENT_UMLAUT:
  2440.   {
  2441.     if (start)
  2442.     {
  2443.       char *val = GetArgData();
  2444.       if (val)
  2445.       {
  2446.         switch (val[0])
  2447.         {
  2448.           case 'a':
  2449.            TexOutput("ä");
  2450.            break;
  2451.           case 'e':
  2452.            TexOutput("ë");
  2453.            break;
  2454.           case 'i':
  2455.            TexOutput("ï");
  2456.            break;
  2457.           case 'o':
  2458.            TexOutput("ö");
  2459.            break;
  2460.           case 'u':
  2461.            TexOutput("ü");
  2462.            break;
  2463.           case 'y':
  2464.            TexOutput("ÿ");
  2465.            break;
  2466.           case 'A':
  2467.            TexOutput("Ä");
  2468.            break;
  2469.           case 'E':
  2470.            TexOutput("Ë");
  2471.            break;
  2472.           case 'I':
  2473.            TexOutput("Ï");
  2474.            break;
  2475.           case 'O':
  2476.            TexOutput("Ö");
  2477.            break;
  2478.           case 'U':
  2479.            TexOutput("Ü");
  2480.            break;
  2481.           case 'Y':
  2482.            TexOutput("Ÿ");
  2483.            break;
  2484.           default:
  2485.            break;
  2486.         }
  2487.       }
  2488.     }
  2489.     return FALSE;
  2490.     break;
  2491.   }
  2492.   case ltACCENT_DOT:
  2493.   {
  2494.     if (start)
  2495.     {
  2496.       char *val = GetArgData();
  2497.       if (val)
  2498.       {
  2499.         switch (val[0])
  2500.         {
  2501.           case 'a':
  2502.            TexOutput("å");
  2503.            break;
  2504.           case 'A':
  2505.            TexOutput("Å");
  2506.            break;
  2507.           default:
  2508.            break;
  2509.         }
  2510.       }
  2511.     }
  2512.     return FALSE;
  2513.     break;
  2514.   }
  2515.   case ltBACKGROUND:
  2516.   {
  2517.     if (start)
  2518.     {
  2519.       char *val = GetArgData();
  2520.       if (val)
  2521.       {
  2522.         bool isPicture = FALSE;
  2523.         char *s = ParseColourString(val, &isPicture);
  2524.         if (isPicture)
  2525.         {
  2526.           if (backgroundImageString)
  2527.             delete[] backgroundImageString;
  2528.           backgroundImageString = copystring(val);
  2529.         }
  2530.         else
  2531.         {
  2532.           if (backgroundColourString)
  2533.             delete[] backgroundColourString;
  2534.           backgroundColourString = copystring(val);
  2535.         }
  2536.       }
  2537.     }
  2538.     return FALSE;
  2539.     break;
  2540.   }
  2541.   case ltBACKGROUNDIMAGE:
  2542.   {
  2543.     if (start)
  2544.     {
  2545.       char *val = GetArgData();
  2546.       if (val)
  2547.       {
  2548.         if (backgroundImageString)
  2549.           delete[] backgroundImageString;
  2550.         backgroundImageString = copystring(val);
  2551.       }
  2552.     }
  2553.     return FALSE;
  2554.     break;
  2555.   }
  2556.   case ltBACKGROUNDCOLOUR:
  2557.   {
  2558.     if (start)
  2559.     {
  2560.       char *val = GetArgData();
  2561.       if (val)
  2562.       {
  2563.         if (backgroundColourString)
  2564.           delete[] backgroundColourString;
  2565.         backgroundColourString = copystring(val);
  2566.       }
  2567.     }
  2568.     return FALSE;
  2569.     break;
  2570.   }
  2571.   case ltTEXTCOLOUR:
  2572.   {
  2573.     if (start)
  2574.     {
  2575.       char *val = GetArgData();
  2576.       if (val)
  2577.       {
  2578.         if (textColourString)
  2579.           delete[] textColourString;
  2580.         textColourString = copystring(val);
  2581.       }
  2582.     }
  2583.     return FALSE;
  2584.     break;
  2585.   }
  2586.   case ltLINKCOLOUR:
  2587.   {
  2588.     if (start)
  2589.     {
  2590.       char *val = GetArgData();
  2591.       if (val)
  2592.       {
  2593.         if (linkColourString)
  2594.           delete[] linkColourString;
  2595.         linkColourString = copystring(val);
  2596.       }
  2597.     }
  2598.     return FALSE;
  2599.     break;
  2600.   }
  2601.   case ltFOLLOWEDLINKCOLOUR:
  2602.   {
  2603.     if (start)
  2604.     {
  2605.       char *val = GetArgData();
  2606.       if (val)
  2607.       {
  2608.         if (followedLinkColourString)
  2609.           delete[] followedLinkColourString;
  2610.         followedLinkColourString = copystring(val);
  2611.       }
  2612.     }
  2613.     return FALSE;
  2614.     break;
  2615.   }
  2616.   case ltACCENT_CADILLA:
  2617.   {
  2618.     if (start)
  2619.     {
  2620.       char *val = GetArgData();
  2621.       if (val)
  2622.       {
  2623.         switch (val[0])
  2624.         {
  2625.           case 'c':
  2626.            TexOutput("ç");
  2627.            break;
  2628.           case 'C':
  2629.            TexOutput("Ç");
  2630.            break;
  2631.           default:
  2632.            break;
  2633.         }
  2634.       }
  2635.     }
  2636.     return FALSE;
  2637.     break;
  2638.   }
  2639. /*
  2640.   case ltFOOTNOTE:
  2641.   case ltFOOTNOTEPOPUP:
  2642.   {
  2643.     if (arg_no == 1)
  2644.       return TRUE;
  2645.     else
  2646.       return FALSE;
  2647.     break;
  2648.   }
  2649. */
  2650.   case ltTABULAR:
  2651.   case ltSUPERTABULAR:
  2652.   {
  2653.     if (arg_no == 1)
  2654.     {
  2655.       if (start)
  2656.       {
  2657.         currentRowNumber = 0;
  2658.         inTabular = TRUE;
  2659.         startRows = TRUE;
  2660.         tableVerticalLineLeft = FALSE;
  2661.         tableVerticalLineRight = FALSE;
  2662.         int currentWidth = 0;
  2663.  
  2664.         char *alignString = copystring(GetArgData());
  2665.         ParseTableArgument(alignString);
  2666.  
  2667.         TexOutput("<TABLE BORDER>\n");
  2668.  
  2669.         // Write the first row formatting for compatibility
  2670.         // with standard Latex
  2671.         if (compatibilityMode)
  2672.         {
  2673.           TexOutput("<TR>\n<TD>");
  2674.           OutputFont();
  2675. /*
  2676.           for (int i = 0; i < noColumns; i++)
  2677.           {
  2678.             currentWidth += TableData[i].width;
  2679.             sprintf(buf, "\\cellx%d", currentWidth);
  2680.             TexOutput(buf);
  2681.           }
  2682.           TexOutput("\\pard\\intbl\n");
  2683. */
  2684.         }
  2685.         delete[] alignString;
  2686.  
  2687.         return FALSE;
  2688.       }
  2689.     }
  2690.     else if (arg_no == 2 && !start)
  2691.     {
  2692.       TexOutput("</TABLE>\n");
  2693.       inTabular = FALSE;
  2694.     }
  2695.     break;
  2696.   }
  2697.   case ltTHEBIBLIOGRAPHY:
  2698.   {
  2699.     if (start && (arg_no == 1))
  2700.     {
  2701.       ReopenFile(&Chapters, &ChaptersName);
  2702.       AddTexRef("bibliography", ChaptersName, "bibliography");
  2703.       SetCurrentSubsectionName("bibliography", ChaptersName);
  2704.  
  2705.       citeCount = 1;
  2706.  
  2707.       SetCurrentOutput(Chapters);
  2708.  
  2709.       char titleBuf[150];
  2710.       if (truncateFilenames)
  2711.         sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
  2712.       else
  2713.         sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
  2714.  
  2715.       HTMLHead();
  2716.       TexOutput("<title>");
  2717.       TexOutput(ReferencesNameString);
  2718.       TexOutput("</title></head>\n");
  2719.       OutputBodyStart();
  2720.  
  2721.       fprintf(Chapters, "<A NAME=\"%s\">\n<H2>%s", "bibliography", ReferencesNameString);
  2722.       AddBrowseButtons("contents", titleBuf, // Up
  2723.                        lastTopic, lastFileName,  // Last topic
  2724.                        "bibliography", ChaptersName); // This topic
  2725.  
  2726.       SetCurrentOutputs(Contents, Chapters);
  2727.       fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), "bibliography");
  2728.  
  2729.       fprintf(Contents, "%s</A>\n", ReferencesNameString);
  2730.       fprintf(Chapters, "</H2>\n</A>\n");
  2731.  
  2732.       SetCurrentOutput(Chapters);
  2733.       return FALSE;
  2734.     }
  2735.     if (!start && (arg_no == 2))
  2736.     {
  2737.     }
  2738.     return TRUE;
  2739.     break;
  2740.   }
  2741.   case ltINDEX:
  2742.   {
  2743.     /* Build up list of keywords associated with topics */
  2744.     if (start)
  2745.     {
  2746. //      char *entry = GetArgData();
  2747.       char buf[300];
  2748.       OutputChunkToString(GetArgChunk(), buf);
  2749.       if (CurrentTopic)
  2750.       {
  2751.         AddKeyWordForTopic(CurrentTopic, buf, currentFileName);
  2752.       }
  2753.     }
  2754.     return FALSE;
  2755.     break;
  2756.   }
  2757.   case ltFCOL:
  2758. //  case ltBCOL:
  2759.   {
  2760.     if (start)
  2761.     {
  2762.       switch (arg_no)
  2763.       {
  2764.         case 1:
  2765.         {
  2766.           char *name = GetArgData();
  2767.           char buf2[10];
  2768.           if (!FindColourHTMLString(name, buf2))
  2769.           {
  2770.             strcpy(buf2, "#000000");
  2771.             char buf[100];
  2772.             sprintf(buf, "Could not find colour name %s", name);
  2773.             OnError(buf);
  2774.           }
  2775.           TexOutput("<FONT COLOR=\"");
  2776.           TexOutput(buf2);
  2777.           TexOutput("\">");
  2778.           break;
  2779.         }
  2780.         case 2:
  2781.         {
  2782.           return TRUE;
  2783.           break;
  2784.         }
  2785.         default:
  2786.           break;
  2787.       }
  2788.     }
  2789.     else
  2790.     {
  2791.       if (arg_no == 2) TexOutput("</FONT>");
  2792.     }
  2793.     return FALSE;
  2794.     break;
  2795.   }
  2796.   case ltINSERTATLEVEL:
  2797.   {
  2798.     // This macro allows you to insert text at a different level
  2799.     // from the current level, e.g. into the Sections from within a subsubsection.
  2800.     if (useWord)
  2801.         return FALSE;
  2802.     static int currentLevelNo = 1;
  2803.     static FILE* oldLevelFile = Chapters;
  2804.     if (start)
  2805.     {
  2806.       switch (arg_no)
  2807.       {
  2808.         case 1:
  2809.         {
  2810.           oldLevelFile = CurrentOutput1;
  2811.  
  2812.           char *str = GetArgData();
  2813.           currentLevelNo = atoi(str);
  2814.           FILE* outputFile;
  2815.           // TODO: cope with article style (no chapters)
  2816.           switch (currentLevelNo)
  2817.           {
  2818.             case 1:
  2819.             {
  2820.                 outputFile = Chapters;
  2821.                 break;
  2822.             }
  2823.             case 2:
  2824.             {
  2825.                 outputFile = Sections;
  2826.                 break;
  2827.             }
  2828.             case 3:
  2829.             {
  2830.                 outputFile = Subsections;
  2831.                 break;
  2832.             }
  2833.             case 4:
  2834.             {
  2835.                 outputFile = Subsubsections;
  2836.                 break;
  2837.             }
  2838.             default:
  2839.             {
  2840.                 outputFile = NULL;
  2841.                 break;
  2842.             }
  2843.           }
  2844.           if (outputFile)
  2845.             CurrentOutput1 = outputFile;
  2846.           return FALSE;
  2847.           break;
  2848.         }
  2849.         case 2:
  2850.         {
  2851.           return TRUE;
  2852.           break;
  2853.         }
  2854.         default:
  2855.           break;
  2856.       }
  2857.       return TRUE;
  2858.     }
  2859.     else
  2860.     {
  2861.         if (arg_no == 2)
  2862.         {
  2863.             CurrentOutput1 = oldLevelFile;
  2864.         }
  2865.         return TRUE;
  2866.     }
  2867.   }
  2868.   default:
  2869.     return DefaultOnArgument(macroId, arg_no, start);
  2870.     break;
  2871.   }
  2872.   return TRUE;
  2873. }
  2874.  
  2875. bool HTMLGo(void)
  2876. {
  2877.   fileId = 0;
  2878.   inVerbatim = FALSE;
  2879.   indentLevel = 0;
  2880.   inTabular = FALSE;
  2881.   startRows = FALSE;
  2882.   tableVerticalLineLeft = FALSE;
  2883.   tableVerticalLineRight = FALSE;
  2884.   noColumns = 0;
  2885.  
  2886.   if (InputFile && OutputFile)
  2887.   {
  2888.     // Do some HTML-specific transformations on all the strings,
  2889.     // recursively
  2890.     Text2HTML(GetTopLevelChunk());
  2891.  
  2892.     char buf[300];
  2893.     if (truncateFilenames)
  2894.       sprintf(buf, "%s.htm", FileRoot);
  2895.     else
  2896.       sprintf(buf, "%s_contents.html", FileRoot);
  2897.     if (TitlepageName) delete[] TitlepageName;
  2898.     TitlepageName = copystring(buf);
  2899.     Titlepage = fopen(buf, "w");
  2900.  
  2901.     if (truncateFilenames)
  2902.       sprintf(buf, "%s_fc.htm", FileRoot);
  2903.     else
  2904.       sprintf(buf, "%s_fcontents.html", FileRoot);
  2905.  
  2906.     contentsFrameName = copystring(buf);
  2907.  
  2908.     Contents = fopen(TmpContentsName, "w");
  2909.  
  2910.     if (htmlFrameContents)
  2911.     {
  2912. //      FrameContents = fopen(TmpFrameContentsName, "w");
  2913.       FrameContents = fopen(contentsFrameName, "w");
  2914.       fprintf(FrameContents, "<HTML>\n<UL>\n");
  2915.     }
  2916.  
  2917.     if (!Titlepage || !Contents)
  2918.     {
  2919.       OnError("Cannot open output file!");
  2920.       return FALSE;
  2921.     }
  2922.     AddTexRef("contents", FileNameFromPath(TitlepageName), ContentsNameString);
  2923.  
  2924.     fprintf(Contents, "<P><P><H2>%s</H2><P><P>\n", ContentsNameString);
  2925.  
  2926.     fprintf(Contents, "<UL>\n");
  2927.  
  2928.     SetCurrentOutput(Titlepage);
  2929.     if (htmlWorkshopFiles) HTMLWorkshopStartContents();
  2930.     OnInform("Converting...");
  2931.  
  2932.     TraverseDocument();
  2933.     fprintf(Contents, "</UL>\n\n");
  2934.  
  2935. //    SetCurrentOutput(Titlepage);
  2936.     fclose(Titlepage);
  2937.  
  2938.     if (Contents)
  2939.     {
  2940. //      fprintf(Titlepage, "\n</BODY></HTML>\n");
  2941.       fclose(Contents);
  2942.       Contents = NULL;
  2943.     }
  2944.  
  2945.     if (FrameContents)
  2946.     {
  2947.       fprintf(FrameContents, "\n</UL>\n");
  2948.       fprintf(FrameContents, "</HTML>\n");
  2949.       fclose(FrameContents);
  2950.       FrameContents = NULL;
  2951.     }
  2952.  
  2953.     if (Chapters)
  2954.     {
  2955.       fprintf(Chapters, "\n</FONT></BODY></HTML>\n");
  2956.       fclose(Chapters);
  2957.       Chapters = NULL;
  2958.     }
  2959.     if (Sections)
  2960.     {
  2961.       fprintf(Sections, "\n</FONT></BODY></HTML>\n");
  2962.       fclose(Sections);
  2963.       Sections = NULL;
  2964.     }
  2965.     if (Subsections && !combineSubSections)
  2966.     {
  2967.       fprintf(Subsections, "\n</FONT></BODY></HTML>\n");
  2968.       fclose(Subsections);
  2969.       Subsections = NULL;
  2970.     }
  2971.     if (Subsubsections && !combineSubSections)
  2972.     {
  2973.       fprintf(Subsubsections, "\n</FONT></BODY></HTML>\n");
  2974.       fclose(Subsubsections);
  2975.       Subsubsections = NULL;
  2976.     }
  2977.     if ( SectionContentsFD )
  2978.     {
  2979.         fclose(SectionContentsFD);
  2980.         SectionContentsFD = NULL;
  2981.     }
  2982.  
  2983.     // Create a temporary file for the title page header, add some info,
  2984.     // and concat the titlepage just generated.
  2985.     // This is necessary in order to put the title of the document
  2986.     // at the TOP of the file within <HEAD>, even though we only find out
  2987.     // what it is later on.
  2988.     FILE *tmpTitle = fopen("title.tmp", "w");
  2989.     if (tmpTitle)
  2990.     {
  2991.       if (DocumentTitle)
  2992.       {
  2993.         SetCurrentOutput(tmpTitle);
  2994.     HTMLHead();
  2995.         TexOutput("\n<HEAD><TITLE>");
  2996.         TraverseChildrenFromChunk(DocumentTitle);
  2997.         TexOutput("</TITLE></HEAD>\n");
  2998.       }
  2999.       else
  3000.       {
  3001.         SetCurrentOutput(tmpTitle);
  3002.     HTMLHeadTo(tmpTitle);
  3003.         if (contentsString)
  3004.           fprintf(tmpTitle, "<TITLE>%s</TITLE></HEAD>\n\n", contentsString);
  3005.         else
  3006.           fprintf(tmpTitle, "<TITLE>%s</TITLE></HEAD>\n\n", FileNameFromPath(FileRoot));
  3007.       }
  3008.  
  3009.       // Output frame information
  3010.       if (htmlFrameContents)
  3011.       {
  3012.         char firstFileName[300];
  3013.         if (truncateFilenames)
  3014.           sprintf(firstFileName, "%s1.htm", FileRoot);
  3015.         else
  3016.           sprintf(firstFileName, "%s1.html", FileRoot);
  3017.  
  3018.         fprintf(tmpTitle, "<FRAMESET COLS=\"30%%,70%%\">\n");
  3019.  
  3020.         fprintf(tmpTitle, "<FRAME SRC=\"%s\">\n", ConvertCase(FileNameFromPath(contentsFrameName)));
  3021.         fprintf(tmpTitle, "<FRAME SRC=\"%s\" NAME=\"mainwindow\">\n", ConvertCase(FileNameFromPath(firstFileName)));
  3022.         fprintf(tmpTitle, "</FRAMESET>\n");
  3023.  
  3024.         fprintf(tmpTitle, "<NOFRAMES>\n");
  3025.       }
  3026.  
  3027.       // Output <BODY...> to temporary title page
  3028.       OutputBodyStart();
  3029.  
  3030.       // Concat titlepage
  3031.       FILE *fd = fopen(TitlepageName, "r");
  3032.       if (fd)
  3033.       {
  3034.         int ch = getc(fd);
  3035.         while (ch != EOF)
  3036.         {
  3037.           putc(ch, tmpTitle);
  3038.           ch = getc(fd);
  3039.         }
  3040.         fclose(fd);
  3041.       }
  3042.  
  3043.       fprintf(tmpTitle, "\n</FONT></BODY>\n");
  3044.  
  3045.       if (htmlFrameContents)
  3046.       {
  3047.         fprintf(tmpTitle, "\n</NOFRAMES>\n");
  3048.       }
  3049.       fprintf(tmpTitle, "\n</HTML>\n");
  3050.  
  3051.       fclose(tmpTitle);
  3052.       if (FileExists(TitlepageName)) wxRemoveFile(TitlepageName);
  3053.       if (!wxRenameFile("title.tmp", TitlepageName))
  3054.       {
  3055.         wxCopyFile("title.tmp", TitlepageName);
  3056.         wxRemoveFile("title.tmp");
  3057.       }
  3058.     }
  3059.  
  3060.     if (lastFileName) delete[] lastFileName;
  3061.     lastFileName = NULL;
  3062.     if (lastTopic) delete[] lastTopic;
  3063.     lastTopic = NULL;
  3064.  
  3065.     if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
  3066.  
  3067.     if (!wxRenameFile(TmpContentsName, ContentsName))
  3068.     {
  3069.       wxCopyFile(TmpContentsName, ContentsName);
  3070.       wxRemoveFile(TmpContentsName);
  3071.     }
  3072.  
  3073.     // Generate .htx file if requested
  3074.     if (htmlIndex)
  3075.     {
  3076.       char htmlIndexName[300];
  3077.       sprintf(htmlIndexName, "%s.htx", FileRoot);
  3078.       GenerateHTMLIndexFile(htmlIndexName);
  3079.     }
  3080.  
  3081.     // Generate HTML Help Workshop files if requested
  3082.     if (htmlWorkshopFiles)
  3083.     {
  3084.       HTMLWorkshopEndContents();
  3085.       GenerateHTMLWorkshopFiles(FileRoot);
  3086.     }
  3087.  
  3088.  
  3089.     return TRUE;
  3090.   }
  3091.  
  3092.   return FALSE;
  3093. }
  3094.  
  3095. // Output .htx index file
  3096. void GenerateHTMLIndexFile(char *fname)
  3097. {
  3098.   FILE *fd = fopen(fname, "w");
  3099.   if (!fd)
  3100.     return;
  3101.  
  3102.   TopicTable.BeginFind();
  3103.   wxNode *node = NULL;
  3104.   while ((node = TopicTable.Next()))
  3105.   {
  3106.     TexTopic *texTopic = (TexTopic *)node->Data();
  3107.     const char *topicName = node->GetKeyString();
  3108.     if (texTopic->filename && texTopic->keywords)
  3109.     {
  3110.       wxNode *node1 = texTopic->keywords->First();
  3111.       while (node1)
  3112.       {
  3113.         char *s = (char *)node1->Data();
  3114.         fprintf(fd, "%s|%s|%s\n", topicName, texTopic->filename, s);
  3115.         node1 = node1->Next();
  3116.       }
  3117.     }
  3118.   }
  3119.   fclose(fd);
  3120. }
  3121.  
  3122.  
  3123.  
  3124.  
  3125.  
  3126.  
  3127.  
  3128. // output .hpp, .hhc and .hhk files:
  3129.  
  3130.  
  3131. void GenerateHTMLWorkshopFiles(char *fname)
  3132. {
  3133.   FILE *f;
  3134.   char buf[300];
  3135.  
  3136.   /* Generate project file : */
  3137.  
  3138.   sprintf(buf, "%s.hhp", fname);
  3139.   f = fopen(buf, "wt");
  3140.   fprintf(f,
  3141.       "[OPTIONS]\n"
  3142.       "Compatibility=1.1\n"
  3143.       "Full-text search=Yes\n"
  3144.       "Contents file=%s.hhc\n"
  3145.       "Compiled file=%s.chm\n"
  3146.       "Default Window=%sHelp\n"
  3147.       "Default topic=%s\n"
  3148.       "Index file=%s.hhk\n"
  3149.       "Title=",
  3150.       FileNameFromPath(fname),
  3151.       FileNameFromPath(fname),
  3152.       FileNameFromPath(fname),
  3153.       FileNameFromPath(TitlepageName),
  3154.       FileNameFromPath(fname)
  3155.       );
  3156.  
  3157.   if (DocumentTitle) {
  3158.     SetCurrentOutput(f);
  3159.     TraverseChildrenFromChunk(DocumentTitle);
  3160.   }
  3161.   else fprintf(f, "(unknown)");
  3162.  
  3163.   fprintf(f, "\n\n[WINDOWS]\n"
  3164.           "%sHelp=,\"%s.hhc\",\"%s.hhk\",\"%s\",,,,,,0x2420,,0x380e,,,,,0,,,",
  3165.           FileNameFromPath(fname),
  3166.           FileNameFromPath(fname),
  3167.           FileNameFromPath(fname),
  3168.           FileNameFromPath(TitlepageName));
  3169.  
  3170.  
  3171.   fprintf(f, "\n\n[FILES]\n");
  3172.   fprintf(f, "%s\n", FileNameFromPath(TitlepageName));
  3173.   for (int i = 1; i <= fileId; i++) {
  3174.     if (truncateFilenames)
  3175.       sprintf(buf, "%s%d.htm", FileNameFromPath(FileRoot), i);
  3176.     else
  3177.       sprintf(buf, "%s%d.html", FileNameFromPath(FileRoot), i);
  3178.     fprintf(f, "%s\n", buf);
  3179.   }
  3180.   fclose(f);
  3181.  
  3182.   /* Generate index file : */
  3183.  
  3184.   sprintf(buf, "%s.hhk", fname);
  3185.   f = fopen(buf, "wt");
  3186.  
  3187.   fprintf(f,
  3188.       "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
  3189.       "<HTML>\n");
  3190.   HTMLHeadTo(f);
  3191.   fprintf(f,
  3192.       "\n"
  3193.       "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n"
  3194.       "<!-- Sitemap 1.0 -->\n"
  3195.       "</HEAD><BODY>\n"
  3196.       "<OBJECT type=\"text/site properties\">\n"
  3197.       " <param name=\"ImageType\" value=\"Folder\">\n"
  3198.       "</OBJECT>\n"
  3199.       "<UL>\n");
  3200.  
  3201.   TopicTable.BeginFind();
  3202.   wxNode *node = NULL;
  3203.   while ((node = TopicTable.Next()))
  3204.   {
  3205.     TexTopic *texTopic = (TexTopic *)node->Data();
  3206.     const char *topicName = node->GetKeyString();
  3207.     if (texTopic->filename && texTopic->keywords)
  3208.     {
  3209.       wxNode *node1 = texTopic->keywords->First();
  3210.       while (node1)
  3211.       {
  3212.         char *s = (char *)node1->Data();
  3213.         fprintf(f,
  3214.             " <LI> <OBJECT type=\"text/sitemap\">\n"
  3215.             "  <param name=\"Local\" value=\"%s#%s\">\n"
  3216.             "  <param name=\"Name\" value=\"%s\">\n"
  3217.             "  </OBJECT>\n",
  3218.         texTopic->filename, topicName, s);
  3219.         node1 = node1->Next();
  3220.       }
  3221.     }
  3222.   }
  3223.  
  3224.   fprintf(f, "</UL>\n");
  3225.   fclose(f);
  3226. }
  3227.  
  3228.  
  3229.  
  3230. static FILE *HTMLWorkshopContents = NULL;
  3231. static int HTMLWorkshopLastLevel = 0;
  3232.  
  3233. void HTMLWorkshopAddToContents(int level, char *s, char *file)
  3234. {
  3235.   int i;
  3236.  
  3237.   if (level > HTMLWorkshopLastLevel)
  3238.     for (i = HTMLWorkshopLastLevel; i < level; i++)
  3239.       fprintf(HTMLWorkshopContents, "<UL>");
  3240.   if (level < HTMLWorkshopLastLevel)
  3241.     for (i = level; i < HTMLWorkshopLastLevel; i++)
  3242.       fprintf(HTMLWorkshopContents, "</UL>");
  3243.  
  3244.   SetCurrentOutput(HTMLWorkshopContents);
  3245.   fprintf(HTMLWorkshopContents,
  3246.             " <LI> <OBJECT type=\"text/sitemap\">\n"
  3247.             "  <param name=\"Local\" value=\"%s#%s\">\n"
  3248.             "  <param name=\"Name\" value=\"",
  3249.         file, s);
  3250.   OutputCurrentSection();
  3251.   fprintf(HTMLWorkshopContents,
  3252.         "\">\n"
  3253.             "  </OBJECT>\n");
  3254.   HTMLWorkshopLastLevel = level;
  3255. }
  3256.  
  3257.  
  3258. void HTMLWorkshopStartContents()
  3259. {
  3260.   char buf[300];
  3261.   sprintf(buf, "%s.hhc", FileRoot);
  3262.   HTMLWorkshopContents = fopen(buf, "wt");
  3263.   HTMLWorkshopLastLevel = 0;
  3264.  
  3265.   fprintf(HTMLWorkshopContents,
  3266.       "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
  3267.       "<HTML>\n");
  3268.   HTMLHeadTo(HTMLWorkshopContents);
  3269.   fprintf(HTMLWorkshopContents,
  3270.       "\n"
  3271.       "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n"
  3272.       "<!-- Sitemap 1.0 -->\n"
  3273.       "</HEAD><BODY>\n"
  3274.       "<OBJECT type=\"text/site properties\">\n"
  3275.       " <param name=\"ImageType\" value=\"Folder\">\n"
  3276.       "</OBJECT>\n"
  3277.       "<UL>\n"
  3278.       "<LI> <OBJECT type=\"text/sitemap\">\n"
  3279.       "<param name=\"Local\" value=\"%s\">\n"
  3280.       "<param name=\"Name\" value=\"Contents\">\n</OBJECT>\n",
  3281.       FileNameFromPath(TitlepageName)
  3282.       );
  3283.  
  3284. }
  3285.  
  3286.  
  3287. void HTMLWorkshopEndContents()
  3288. {
  3289.   for (int i = HTMLWorkshopLastLevel; i >= 0; i--)
  3290.     fprintf(HTMLWorkshopContents, "</UL>\n");
  3291.   fclose(HTMLWorkshopContents);
  3292. }
  3293.