1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Converts Latex to HTML 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  32 extern wxHashTable TexReferences
; 
  35 extern void DecToHex(int, char *); 
  36 void GenerateHTMLIndexFile(char *fname
); 
  38 void GenerateHTMLWorkshopFiles(char *fname
); 
  39 void HTMLWorkshopAddToContents(int level
, char *s
, char *file
); 
  40 void HTMLWorkshopStartContents(); 
  41 void HTMLWorkshopEndContents(); 
  43 void OutputContentsFrame(void); 
  45 #include "readshg.h" // Segmented hypergraphics parsing 
  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
; 
  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; 
  67 bool subsectionStarted 
= FALSE
; 
  69 // Which column of a row are we in? (Assumes no nested tables, of course) 
  70 int currentColumn 
= 0; 
  72 // Are we in verbatim mode? If so, format differently. 
  73 static bool inVerbatim 
= FALSE
; 
  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
; 
  80 // This is defined in the Tex2Any library. 
  81 extern char *BigBuffer
; 
  83 // DHS Two-column table dimensions. 
  84 static int TwoColWidthA 
= -1; 
  85 static int TwoColWidthB 
= -1; 
  88 class HyperReference
: public wxObject
 
  93   HyperReference(char *name
, char *file
) 
  95     if (name
) refName 
= copystring(name
); 
  96     if (file
) refFile 
= copystring(file
); 
 100 class TexNextPage
: public wxObject
 
 105   TexNextPage(char *theLabel
, char *theFile
) 
 107     label 
= copystring(theLabel
); 
 108     filename 
= copystring(theFile
); 
 117 wxHashTable 
TexNextPages(wxKEY_STRING
); 
 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
; 
 129 static void SetCurrentTopic(char *s
) 
 131   if (CurrentTopic
) delete[] CurrentTopic
; 
 132   CurrentTopic 
= copystring(s
); 
 135 void SetCurrentChapterName(char *s
, char *file
) 
 137   if (CurrentChapterName
) delete[] CurrentChapterName
; 
 138   CurrentChapterName 
= copystring(s
); 
 139   if (CurrentChapterFile
) delete[] CurrentChapterFile
; 
 140   CurrentChapterFile 
= copystring(file
); 
 142   currentFileName 
= CurrentChapterFile
; 
 146 void SetCurrentSectionName(char *s
, char *file
) 
 148   if (CurrentSectionName
) delete[] CurrentSectionName
; 
 149   CurrentSectionName 
= copystring(s
); 
 150   if (CurrentSectionFile
) delete[] CurrentSectionFile
; 
 151   CurrentSectionFile 
= copystring(file
); 
 153   currentFileName 
= CurrentSectionFile
; 
 156 void SetCurrentSubsectionName(char *s
, char *file
) 
 158   if (CurrentSubsectionName
) delete[] CurrentSubsectionName
; 
 159   CurrentSubsectionName 
= copystring(s
); 
 160   if (CurrentSubsectionFile
) delete[] CurrentSubsectionFile
; 
 161   CurrentSubsectionFile 
= copystring(file
); 
 162   currentFileName 
= CurrentSubsectionFile
; 
 165 void SetCurrentSubsubsectionName(char *s
, char *file
) 
 167   if (CurrentSubsubsectionName
) delete[] CurrentSubsubsectionName
; 
 168   CurrentSubsubsectionName 
= copystring(s
); 
 169   if (CurrentSubsubsectionFile
) delete[] CurrentSubsubsectionFile
; 
 170   CurrentSubsubsectionFile 
= copystring(file
); 
 171   currentFileName 
= CurrentSubsubsectionFile
; 
 176  * Close former filedescriptor and reopen using another filename. 
 180 void ReopenFile(FILE **fd
, char **fileName
) 
 184     fprintf(*fd
, "\n</BODY></HTML>\n"); 
 189   if (truncateFilenames
) 
 190     sprintf(buf
, "%s%d.htm", FileRoot
, fileId
); 
 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"); 
 200  * Reopen section contents file, i.e. the index appended to each section 
 201  * in subsectionCombine mode 
 204 static char *SectionContentsFilename 
= NULL
; 
 205 static FILE *SectionContentsFD 
= NULL
; 
 207 void ReopenSectionContentsFile(void) 
 209     if ( SectionContentsFD 
) 
 211         fclose(SectionContentsFD
); 
 213     if ( SectionContentsFilename 
) 
 214         delete[] SectionContentsFilename
; 
 215     SectionContentsFD 
= NULL
; 
 216     SectionContentsFilename 
= NULL
; 
 218     // Create the name from the current section filename 
 219     if ( CurrentSectionFile 
) 
 222         strcpy(buf
, CurrentSectionFile
); 
 223         wxStripExtension(buf
); 
 225         SectionContentsFilename 
= copystring(buf
); 
 227         SectionContentsFD 
= fopen(SectionContentsFilename
, "w"); 
 233  * Given a TexChunk with a string value, scans through the string 
 234  * converting Latex-isms into HTML-isms, such as 2 newlines -> <P>. 
 238 void ProcessText2HTML(TexChunk 
*chunk
) 
 240   bool changed 
= FALSE
; 
 244   int len 
= strlen(chunk
->value
); 
 247     ch 
= chunk
->value
[i
]; 
 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)))) 
 254       BigBuffer
[ptr
] = 0; strcat(BigBuffer
, "<P>\n\n"); ptr 
+= 5; 
 258     else if (!inVerbatim 
&& ch 
== '`' && (len 
>= i
+1 && chunk
->value
[i
+1] == '`')) 
 260       BigBuffer
[ptr
] = '"'; ptr 
++; 
 264     else if (!inVerbatim 
&& ch 
== '`') // Change ` to ' 
 266       BigBuffer
[ptr
] = 39; ptr 
++; 
 270     else if (ch 
== '<') // Change < to < 
 273       strcat(BigBuffer
, "<"); 
 278     else if (ch 
== '>') // Change > to > 
 281       strcat(BigBuffer
, ">"); 
 298     chunk
->value 
= copystring(BigBuffer
); 
 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. 
 310 void Text2HTML(TexChunk 
*chunk
) 
 313   if (stopRunning
) return; 
 317     case CHUNK_TYPE_MACRO
: 
 319       TexMacroDef 
*def 
= chunk
->def
; 
 321       if (def 
&& def
->ignore
) 
 324       if (def 
&& (def
->macroId 
== ltVERBATIM 
|| def
->macroId 
== ltVERB 
|| def
->macroId 
== ltSPECIAL
)) 
 327       wxNode 
*node 
= chunk
->children
.First(); 
 330         TexChunk 
*child_chunk 
= (TexChunk 
*)node
->Data(); 
 331         Text2HTML(child_chunk
); 
 335       if (def 
&& (def
->macroId 
== ltVERBATIM 
|| def
->macroId 
== ltVERB 
|| def
->macroId 
== ltSPECIAL
)) 
 342       wxNode 
*node 
= chunk
->children
.First(); 
 345         TexChunk 
*child_chunk 
= (TexChunk 
*)node
->Data(); 
 346         Text2HTML(child_chunk
); 
 352     case CHUNK_TYPE_STRING
: 
 355         ProcessText2HTML(chunk
); 
 362  * Add appropriate browse buttons to this page. 
 366 void AddBrowseButtons(char *upLabel
, char *upFilename
, 
 367   char *previousLabel
, char *previousFilename
, 
 368   char *thisLabel
, char *thisFilename
) 
 370   char contentsReferenceBuf
[80]; 
 371   char upReferenceBuf
[80]; 
 372   char backReferenceBuf
[80]; 
 373   char forwardReferenceBuf
[80]; 
 374   if (htmlBrowseButtons 
== HTML_BUTTONS_NONE
) 
 377   char *contentsReference 
= NULL
; 
 378   if (htmlBrowseButtons 
== HTML_BUTTONS_TEXT
) 
 379     contentsReference 
= ContentsNameString
; 
 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")); 
 387   char *upReference 
= NULL
; 
 388   if (htmlBrowseButtons 
== HTML_BUTTONS_TEXT
) 
 389     upReference 
= UpNameString
; 
 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")); 
 397   char *backReference 
= NULL
; 
 398   if (htmlBrowseButtons 
== HTML_BUTTONS_TEXT
) 
 399     backReference 
= "<<"; 
 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")); 
 407   char *forwardReference 
= NULL
; 
 408   if (htmlBrowseButtons 
== HTML_BUTTONS_TEXT
) 
 409     forwardReference 
= ">>"; 
 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")); 
 417   TexOutput("<CENTER>"); 
 426   if (truncateFilenames
) 
 429     strcpy(buf1
, ConvertCase(FileNameFromPath(FileRoot
))); 
 430     sprintf(buf
, "\n<A HREF=\"%s.%s\">%s</A> ", buf1
, ConvertCase("htm"), contentsReference
); 
 435     strcpy(buf1
, ConvertCase(FileNameFromPath(FileRoot
))); 
 436     sprintf(buf
, "\n<A HREF=\"%s%s\">%s</A> ", buf1
, ConvertCase("_contents.html"), contentsReference
); 
 438 //  TexOutput("<NOFRAMES>"); 
 440 //  TexOutput("</NOFRAMES>"); 
 447   if (upLabel 
&& upFilename
) 
 449     if (strlen(upLabel
) > 0) 
 450       sprintf(buf
, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(upFilename
), upLabel
, upReference
); 
 452       sprintf(buf
, "<A HREF=\"%s\">%s</A> ", ConvertCase(upFilename
), upReference
); 
 453     if (strcmp(upLabel
, "contents") == 0) 
 455 //      TexOutput("<NOFRAMES>"); 
 457 //      TexOutput("</NOFRAMES>"); 
 468   if (previousLabel 
&& previousFilename
) 
 470     sprintf(buf
, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(previousFilename
), previousLabel
, backReference
); 
 471     if (strcmp(previousLabel
, "contents") == 0) 
 473 //      TexOutput("<NOFRAMES>"); 
 475 //      TexOutput("</NOFRAMES>"); 
 482     // A placeholder so the buttons don't keep moving position 
 483     sprintf(buf
, "%s ", backReference
); 
 487   char *nextLabel 
= NULL
; 
 488   char *nextFilename 
= NULL
; 
 490   // Get the next page, and record the previous page's 'next' page 
 492   TexNextPage 
*nextPage 
= (TexNextPage 
*)TexNextPages
.Get(thisLabel
); 
 495     nextLabel 
= nextPage
->label
; 
 496     nextFilename 
= nextPage
->filename
; 
 498   if (previousLabel 
&& previousFilename
) 
 500     TexNextPage 
*oldNextPage 
= (TexNextPage 
*)TexNextPages
.Get(previousLabel
); 
 504       TexNextPages
.Delete(previousLabel
); 
 506     TexNextPage 
*newNextPage 
= new TexNextPage(thisLabel
, thisFilename
); 
 507     TexNextPages
.Put(previousLabel
, newNextPage
); 
 515   if (nextLabel 
&& nextFilename
) 
 517     sprintf(buf
, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(nextFilename
), nextLabel
, forwardReference
); 
 522     // A placeholder so the buttons don't keep moving position 
 523     sprintf(buf
, "%s ", forwardReference
); 
 528    * Horizontal rule to finish it off nicely. 
 531   TexOutput("</CENTER>"); 
 534   // Update last topic/filename 
 536     delete[] lastFileName
; 
 537   lastFileName 
= copystring(thisFilename
); 
 540   lastTopic 
= copystring(thisLabel
); 
 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
) 
 547   static char resStr
[300]; 
 548   strcpy(resStr
, bkStr
); 
 549   char *tok1 
= strtok(resStr
, ";"); 
 550   char *tok2 
= strtok(NULL
, ";"); 
 561       char *tok3 
= strtok(NULL
, ";"); 
 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
); 
 574         DecToHex(green
, buf
); 
 586 // Output start of <BODY> block 
 587 void OutputBodyStart(void) 
 589   TexOutput("\n<BODY"); 
 590   if (backgroundImageString
) 
 592     bool isPicture 
= FALSE
; 
 593     char *s 
= ParseColourString(backgroundImageString
, &isPicture
); 
 596       TexOutput(" BACKGROUND=\""); TexOutput(s
); TexOutput("\""); 
 599   if (backgroundColourString
) 
 601     bool isPicture 
= FALSE
; 
 602     char *s 
= ParseColourString(backgroundColourString
, &isPicture
); 
 605       TexOutput(" BGCOLOR="); TexOutput(s
); 
 609   // Set foreground text colour, if one is specified 
 610   if (textColourString
) 
 612     bool isPicture 
= FALSE
; 
 613     char *s 
= ParseColourString(textColourString
, &isPicture
); 
 616       TexOutput(" TEXT="); TexOutput(s
); 
 619   // Set link text colour, if one is specified 
 620   if (linkColourString
) 
 622     bool isPicture 
= FALSE
; 
 623     char *s 
= ParseColourString(linkColourString
, &isPicture
); 
 626       TexOutput(" LINK="); TexOutput(s
); 
 629   // Set followed link text colour, if one is specified 
 630   if (followedLinkColourString
) 
 632     bool isPicture 
= FALSE
; 
 633     char *s 
= ParseColourString(followedLinkColourString
, &isPicture
); 
 636       TexOutput(" VLINK="); TexOutput(s
); 
 642 // Called on start/end of macro examination 
 643 void HTMLOnMacro(int macroId
, int no_args
, bool start
) 
 649   case ltCHAPTERHEADING
: 
 657       if (macroId 
!= ltCHAPTERSTAR
) 
 660       SetCurrentOutput(NULL
); 
 661       startedSections 
= TRUE
; 
 663       char *topicName 
= FindTopicName(GetNextChunk()); 
 664       ReopenFile(&Chapters
, &ChaptersName
); 
 665       AddTexRef(topicName
, ChaptersName
, ChapterNameString
); 
 667       SetCurrentChapterName(topicName
, ChaptersName
); 
 668       if (htmlWorkshopFiles
) HTMLWorkshopAddToContents(0, topicName
, ChaptersName
); 
 670       SetCurrentOutput(Chapters
); 
 672       TexOutput("<head><title>"); 
 673       OutputCurrentSection(); // Repeat section header 
 674       TexOutput("</title></head>\n"); 
 678       if (truncateFilenames
) 
 679         sprintf(titleBuf
, "%s.htm", FileNameFromPath(FileRoot
)); 
 681         sprintf(titleBuf
, "%s_contents.html", FileNameFromPath(FileRoot
)); 
 683       fprintf(Chapters
, "<A NAME=\"%s\"></A>", topicName
); 
 685       AddBrowseButtons("", titleBuf
, // Up 
 686                        lastTopic
, lastFileName
,  // Last topic 
 687                        topicName
, ChaptersName
); // This topic 
 689       fprintf(Contents
, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName
), topicName
); 
 691       if (htmlFrameContents 
&& FrameContents
) 
 693         SetCurrentOutput(FrameContents
); 
 694         fprintf(FrameContents
, "\n<LI><A HREF=\"%s#%s\" TARGET=\"mainwindow\">", ConvertCase(ChaptersName
), topicName
); 
 695         OutputCurrentSection(); 
 696         fprintf(FrameContents
, "</A>\n"); 
 699       SetCurrentOutputs(Contents
, Chapters
); 
 700       fprintf(Chapters
, "\n<H2>"); 
 701       OutputCurrentSection(); 
 702       fprintf(Contents
, "</A>\n"); 
 703       fprintf(Chapters
, "</H2>\n"); 
 705       SetCurrentOutput(Chapters
); 
 707       // Add this section title to the list of keywords 
 710         OutputCurrentSectionToString(wxBuffer
); 
 711         AddKeyWordForTopic(topicName
, wxBuffer
, ConvertCase(currentFileName
)); 
 718   case ltSECTIONHEADING
: 
 725       subsectionStarted 
= FALSE
; 
 727       if (macroId 
!= ltSECTIONSTAR
) 
 730       SetCurrentOutput(NULL
); 
 731       startedSections 
= TRUE
; 
 733       char *topicName 
= FindTopicName(GetNextChunk()); 
 734       ReopenFile(&Sections
, &SectionsName
); 
 735       AddTexRef(topicName
, SectionsName
, SectionNameString
); 
 737       SetCurrentSectionName(topicName
, SectionsName
); 
 738       if (htmlWorkshopFiles
) HTMLWorkshopAddToContents(1, topicName
, SectionsName
); 
 740       SetCurrentOutput(Sections
); 
 741       TexOutput("<head><title>"); 
 742       OutputCurrentSection(); 
 743       TexOutput("</title></head>\n"); 
 746       fprintf(Sections
, "<A NAME=\"%s\"></A>", topicName
); 
 747       AddBrowseButtons(CurrentChapterName
, CurrentChapterFile
, // Up 
 748                        lastTopic
, lastFileName
,  // Last topic 
 749                        topicName
, SectionsName
); // This topic 
 751       FILE *jumpFrom 
= ((DocumentStyle 
== LATEX_ARTICLE
) ? Contents 
: Chapters
); 
 753       SetCurrentOutputs(jumpFrom
, Sections
); 
 754       if (DocumentStyle 
== LATEX_ARTICLE
) 
 755         fprintf(jumpFrom
, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(SectionsName
), topicName
); 
 757         fprintf(jumpFrom
, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SectionsName
), topicName
); 
 759       fprintf(Sections
, "\n<H2>"); 
 760       OutputCurrentSection(); 
 762       if (DocumentStyle 
== LATEX_ARTICLE
) 
 763         fprintf(jumpFrom
, "</A>\n"); 
 765         fprintf(jumpFrom
, "</B></A><BR>\n"); 
 766       fprintf(Sections
, "</H2>\n"); 
 768       SetCurrentOutput(Sections
); 
 769       // Add this section title to the list of keywords 
 772         OutputCurrentSectionToString(wxBuffer
); 
 773         AddKeyWordForTopic(topicName
, wxBuffer
, currentFileName
); 
 779   case ltSUBSECTIONSTAR
: 
 780   case ltMEMBERSECTION
: 
 781   case ltFUNCTIONSECTION
: 
 787         OnError("You cannot have a subsection before a section!"); 
 793           if (macroId 
!= ltSUBSECTIONSTAR
) 
 796           if ( combineSubSections 
&& !subsectionStarted 
) 
 798             // Read old .con file in at this point 
 800             strcpy(buf
, CurrentSectionFile
); 
 801             wxStripExtension(buf
); 
 803             FILE *fd 
= fopen(buf
, "r"); 
 814             fprintf(Sections
, "<P>\n"); 
 816             // Close old file, create a new file for the sub(sub)section contents entries 
 817             ReopenSectionContentsFile(); 
 820           startedSections 
= TRUE
; 
 821           subsectionStarted 
= TRUE
; 
 823           char *topicName 
= FindTopicName(GetNextChunk()); 
 825           if ( !combineSubSections 
) 
 827             SetCurrentOutput(NULL
); 
 828             ReopenFile(&Subsections
, &SubsectionsName
); 
 829             AddTexRef(topicName
, SubsectionsName
, SubsectionNameString
); 
 830             SetCurrentSubsectionName(topicName
, SubsectionsName
); 
 831             if (htmlWorkshopFiles
) HTMLWorkshopAddToContents(2, topicName
, SubsectionsName
); 
 832             SetCurrentOutput(Subsections
); 
 834             TexOutput("<head><title>"); 
 835             OutputCurrentSection(); 
 836             TexOutput("</title></head>\n"); 
 839             fprintf(Subsections
, "<A NAME=\"%s\"></A>", topicName
); 
 840             AddBrowseButtons(CurrentSectionName
, CurrentSectionFile
, // Up 
 841                            lastTopic
, lastFileName
,  // Last topic 
 842                            topicName
, SubsectionsName
); // This topic 
 844             SetCurrentOutputs(Sections
, Subsections
); 
 845             fprintf(Sections
, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsectionsName
), topicName
); 
 847             fprintf(Subsections
, "\n<H3>"); 
 848             OutputCurrentSection(); 
 849             fprintf(Sections
, "</B></A><BR>\n"); 
 850             fprintf(Subsections
, "</H3>\n"); 
 852             SetCurrentOutput(Subsections
); 
 856             AddTexRef(topicName
, SectionsName
, SubsectionNameString
); 
 857             SetCurrentSubsectionName(topicName
, SectionsName
); 
 859 //            if ( subsectionNo != 0 ) 
 860             fprintf(Sections
, "\n<HR>\n"); 
 862             // We're putting everything into the section file 
 863             fprintf(Sections
, "<A NAME=\"%s\"></A>", topicName
); 
 864             fprintf(Sections
, "\n<H3>"); 
 865             OutputCurrentSection(); 
 866             fprintf(Sections
, "</H3>\n"); 
 868             SetCurrentOutput(SectionContentsFD
); 
 869             fprintf(SectionContentsFD
, "<A HREF=\"#%s\">", topicName
); 
 870             OutputCurrentSection(); 
 871             TexOutput("</A><BR>\n"); 
 873             if (htmlWorkshopFiles
) HTMLWorkshopAddToContents(2, topicName
, SectionsName
); 
 874             SetCurrentOutput(Sections
); 
 876           // Add this section title to the list of keywords 
 879             OutputCurrentSectionToString(wxBuffer
); 
 880             AddKeyWordForTopic(topicName
, wxBuffer
, currentFileName
); 
 887   case ltSUBSUBSECTION
: 
 888   case ltSUBSUBSECTIONSTAR
: 
 892       if (!Subsections 
&& !combineSubSections
) 
 894         OnError("You cannot have a subsubsection before a subsection!"); 
 898         if (macroId 
!= ltSUBSUBSECTIONSTAR
) 
 901         startedSections 
= TRUE
; 
 903         char *topicName 
= FindTopicName(GetNextChunk()); 
 905         if ( !combineSubSections 
) 
 907             SetCurrentOutput(NULL
); 
 908             ReopenFile(&Subsubsections
, &SubsubsectionsName
); 
 909             AddTexRef(topicName
, SubsubsectionsName
, SubsubsectionNameString
); 
 910             SetCurrentSubsubsectionName(topicName
, SubsubsectionsName
); 
 911             if (htmlWorkshopFiles
) HTMLWorkshopAddToContents(3, topicName
, SubsubsectionsName
); 
 913             SetCurrentOutput(Subsubsections
); 
 914             TexOutput("<head><title>"); 
 915             OutputCurrentSection(); 
 916             TexOutput("</title></head>\n"); 
 919             fprintf(Subsubsections
, "<A NAME=\"%s\"></A>", topicName
); 
 921             AddBrowseButtons(CurrentSubsectionName
, CurrentSubsectionFile
, // Up 
 922                          lastTopic
, lastFileName
,  // Last topic 
 923                          topicName
, SubsubsectionsName
); // This topic 
 925             SetCurrentOutputs(Subsections
, Subsubsections
); 
 926             fprintf(Subsections
, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsubsectionsName
), topicName
); 
 928             fprintf(Subsubsections
, "\n<H3>"); 
 929             OutputCurrentSection(); 
 930             fprintf(Subsections
, "</B></A><BR>\n"); 
 931             fprintf(Subsubsections
, "</H3>\n"); 
 935             AddTexRef(topicName
, SectionsName
, SubsubsectionNameString
); 
 936             SetCurrentSubsectionName(topicName
, SectionsName
); 
 937             fprintf(Sections
, "\n<HR>\n"); 
 939             // We're putting everything into the section file 
 940             fprintf(Sections
, "<A NAME=\"%s\"></A>", topicName
); 
 941             fprintf(Sections
, "\n<H3>"); 
 942             OutputCurrentSection(); 
 943             fprintf(Sections
, "</H3>\n"); 
 944 /* TODO: where do we put subsubsection contents entry - indented, with subsection entries? 
 945             SetCurrentOutput(SectionContentsFD); 
 946             fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName); 
 947             OutputCurrentSection(); 
 948             TexOutput("</A><BR>"); 
 950             if (htmlWorkshopFiles
) HTMLWorkshopAddToContents(2, topicName
, SectionsName
); 
 951             SetCurrentOutput(Sections
); 
 954         // Add this section title to the list of keywords 
 957           OutputCurrentSectionToString(wxBuffer
); 
 958           AddKeyWordForTopic(topicName
, wxBuffer
, currentFileName
); 
 967     if ( !combineSubSections 
) 
 968         SetCurrentOutput(Subsections
); 
 970         SetCurrentOutput(Sections
); 
 981     if ( !combineSubSections 
) 
 982         SetCurrentOutput(Subsections
); 
 984         SetCurrentOutput(Sections
); 
 995     if ( !combineSubSections 
) 
 996         SetCurrentOutput(Subsections
); 
 998         SetCurrentOutput(Sections
); 
1009 //      TexOutput("<B>void</B>"); 
1017       TexOutput("wxCLIPS"); 
1023   case ltSPECIALAMPERSAND
: 
1029         // End cell, start cell 
1032         // Start new row and cell, setting alignment for the first cell. 
1033         if (currentColumn 
< noColumns
) 
1037         if (TableData
[currentColumn
].justification 
== 'c') 
1038           sprintf(buf
, "\n<TD ALIGN=CENTER>"); 
1039         else if (TableData
[currentColumn
].justification 
== 'r') 
1040           sprintf(buf
, "\n<TD ALIGN=RIGHT>"); 
1041         else if (TableData
[currentColumn
].absWidth
) 
1043           // Convert from points * 20 into pixels. 
1044           int points 
= TableData
[currentColumn
].width 
/ 20; 
1046           // Say the display is 100 DPI (dots/pixels per inch). 
1047           // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots. 
1048           int pixels 
= (int)(points 
* 100.0 / 72.0); 
1049           sprintf(buf
, "<TD ALIGN=CENTER WIDTH=%d>", pixels
); 
1052           sprintf(buf
, "\n<TD ALIGN=LEFT>"); 
1060   case ltBACKSLASHCHAR
: 
1066         // End row. In fact, tables without use of \row or \ruledrow isn't supported for 
1067         // HTML: the syntax is too different (e.g. how do we know where to put the first </TH> 
1068         // if we've ended the last row?). So normally you wouldn't use \\ to end a row. 
1069         TexOutput("</TR>\n"); 
1072         TexOutput("<BR>\n"); 
1083       // Start new row and cell, setting alignment for the first cell. 
1085       if (TableData
[currentColumn
].justification 
== 'c') 
1086         sprintf(buf
, "<TR>\n<TD ALIGN=CENTER>"); 
1087       else if (TableData
[currentColumn
].justification 
== 'r') 
1088         sprintf(buf
, "<TR>\n<TD ALIGN=RIGHT>"); 
1089       else if (TableData
[currentColumn
].absWidth
) 
1091         // Convert from points * 20 into pixels. 
1092         int points 
= TableData
[currentColumn
].width 
/ 20; 
1094         // Say the display is 100 DPI (dots/pixels per inch). 
1095         // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots. 
1096         int pixels 
= (int)(points 
* 100.0 / 72.0); 
1097         sprintf(buf
, "<TR>\n<TD ALIGN=CENTER WIDTH=%d>", pixels
); 
1100         sprintf(buf
, "<TR>\n<TD ALIGN=LEFT>"); 
1106       // Start new row and cell 
1107       TexOutput("</TD>\n</TR>\n"); 
1111   // HTML-only: break until the end of the picture (both margins are clear). 
1115       TexOutput("<BR CLEAR=ALL>"); 
1118   case ltRTFSP
:  // Explicit space, RTF only 
1120   case ltSPECIALTILDE
: 
1134         TexOutput("<UL><UL>\n"); 
1136         TexOutput("</UL></UL>\n"); 
1142 //  case ltTWOCOLLIST: 
1149       if (macroId 
== ltENUMERATE
) 
1150         listType 
= LATEX_ENUMERATE
; 
1151       else if (macroId 
== ltITEMIZE
) 
1152         listType 
= LATEX_ITEMIZE
; 
1154         listType 
= LATEX_DESCRIPTION
; 
1156       itemizeStack
.Insert(new ItemizeStruc(listType
)); 
1160           TexOutput("<UL>\n"); 
1162         case LATEX_ENUMERATE
: 
1163           TexOutput("<OL>\n"); 
1165         case LATEX_DESCRIPTION
: 
1167           TexOutput("<DL>\n"); 
1174       if (itemizeStack
.First()) 
1176         ItemizeStruc 
*struc 
= (ItemizeStruc 
*)itemizeStack
.First()->Data(); 
1177         switch (struc
->listType
) 
1180             TexOutput("</UL>\n"); 
1182           case LATEX_ENUMERATE
: 
1183             TexOutput("</OL>\n"); 
1185           case LATEX_DESCRIPTION
: 
1187             TexOutput("</DL>\n"); 
1192         delete itemizeStack
.First(); 
1200         TexOutput("\n<TABLE>\n"); 
1202         TexOutput("\n</TABLE>\n"); 
1215 /* For footnotes we need to output the text at the bottom of the page and 
1216  * insert a reference to it. Is it worth the trouble... 
1218   case ltFOOTNOTEPOPUP: 
1224     else TexOutput("</FN>"); 
1232     else TexOutput("</TT>"); 
1240       sprintf(buf
, "<PRE>\n"); 
1243     else TexOutput("</PRE>\n"); 
1251       TexOutput("<CENTER>"); 
1253     else TexOutput("</CENTER>"); 
1261       TexOutput("{\\ql "); 
1263     else TexOutput("}\\par\\pard\n"); 
1272       TexOutput("{\\qr "); 
1274     else TexOutput("}\\par\\pard\n"); 
1282       // Netscape extension 
1283       TexOutput("<FONT SIZE=2>"); 
1285     else TexOutput("</FONT>"); 
1292       // Netscape extension 
1293       TexOutput("<FONT SIZE=1>"); 
1295     else TexOutput("</FONT>"); 
1302       // Netscape extension 
1303       TexOutput("<FONT SIZE=3>"); 
1305     else TexOutput("</FONT>"); 
1312       // Netscape extension 
1313       TexOutput("<FONT SIZE=4>"); 
1315     else TexOutput("</FONT>"); 
1322       // Netscape extension 
1323       TexOutput("<FONT SIZE=5>"); 
1325     else TexOutput("</FONT>"); 
1332       // Netscape extension 
1333       TexOutput("<FONT SIZE=6>"); 
1335     else TexOutput("</FONT>"); 
1346     else TexOutput("</B>"); 
1357     else TexOutput("</I>"); 
1367     else TexOutput("</EM>"); 
1376     else TexOutput("</UL>"); 
1387     else TexOutput("</TT>"); 
1393       TexOutput("©", TRUE
); 
1399       TexOutput("®", TRUE
); 
1405     if (start
) TexOutput("<--"); 
1410     if (start
) TexOutput("<=="); 
1415       if (start
) TexOutput("-->"); 
1420     if (start
) TexOutput("==>"); 
1423   case ltLEFTRIGHTARROW
: 
1425     if (start
) TexOutput("<-->"); 
1428   case ltLEFTRIGHTARROW2
: 
1430     if (start
) TexOutput("<==>"); 
1443       wxNode 
*node 
= itemizeStack
.First(); 
1446         ItemizeStruc 
*struc 
= (ItemizeStruc 
*)node
->Data(); 
1447         struc
->currentItem 
+= 1; 
1448         if (struc
->listType 
== LATEX_DESCRIPTION
) 
1450           if (descriptionItemArg
) 
1453             TraverseChildrenFromChunk(descriptionItemArg
); 
1455             descriptionItemArg 
= NULL
; 
1467     if (start 
&& DocumentTitle 
&& DocumentAuthor
) 
1469       // Add a special label for the contents page. 
1470 //      TexOutput("<CENTER>\n"); 
1471       TexOutput("<A NAME=\"contents\">"); 
1472       TexOutput("<H2 ALIGN=CENTER>\n"); 
1473       TraverseChildrenFromChunk(DocumentTitle
); 
1476       TexOutput("</A>\n"); 
1477       TexOutput("<P>\n\n"); 
1478       TexOutput("<H3 ALIGN=CENTER>"); 
1479       TraverseChildrenFromChunk(DocumentAuthor
); 
1480       TexOutput("</H3><P>\n\n"); 
1483         TexOutput("<H3 ALIGN=CENTER>"); 
1484         TraverseChildrenFromChunk(DocumentDate
); 
1485         TexOutput("</H3><P>\n\n"); 
1487 //      TexOutput("\n</CENTER>\n"); 
1488       TexOutput("\n<P><HR><P>\n"); 
1491       // Now do optional frame contents page 
1492       if (htmlFrameContents && FrameContents) 
1494         SetCurrentOutput(FrameContents); 
1496         // Add a special label for the contents page. 
1497         TexOutput("<CENTER>\n"); 
1498         TexOutput("<H3>\n"); 
1499         TraverseChildrenFromChunk(DocumentTitle); 
1502         TexOutput("</A>\n"); 
1503         TexOutput("<P>\n\n"); 
1505         TraverseChildrenFromChunk(DocumentAuthor); 
1506         TexOutput("</H3><P>\n\n"); 
1510           TraverseChildrenFromChunk(DocumentDate); 
1511           TexOutput("</H4><P>\n\n"); 
1513         TexOutput("\n</CENTER>\n"); 
1514         TexOutput("<P><HR><P>\n"); 
1516         SetCurrentOutput(Titlepage); 
1529       helpRefFilename 
= NULL
; 
1534   case ltBIBLIOGRAPHY
: 
1538       DefaultOnMacro(macroId
, no_args
, start
); 
1542       DefaultOnMacro(macroId
, no_args
, start
); 
1543       TexOutput("</DL>\n"); 
1551       TexOutput("<HR>\n"); 
1559       TexOutput("<HR>\n"); 
1563   case ltTABLEOFCONTENTS
: 
1567       FILE *fd 
= fopen(ContentsName
, "r"); 
1573           putc(ch
, Titlepage
); 
1580         TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n"); 
1581         OnInform("Run Tex2RTF again to include contents page."); 
1602       TexOutput("<BLOCKQUOTE>"); 
1604       TexOutput("</BLOCKQUOTE>"); 
1613         TexOutput("\n<CAPTION>"); 
1621           if (DocumentStyle 
!= LATEX_ARTICLE
) 
1622             sprintf(figBuf
, "%s %d.%d: ", FigureNameString
, chapterNo
, figureNo
); 
1624             sprintf(figBuf
, "%s %d: ", FigureNameString
, figureNo
); 
1630           if (DocumentStyle 
!= LATEX_ARTICLE
) 
1631             sprintf(figBuf
, "%s %d.%d: ", TableNameString
, chapterNo
, tableNo
); 
1633             sprintf(figBuf
, "%s %d: ", TableNameString
, tableNo
); 
1641         TexOutput("\n</CAPTION>\n"); 
1643       char *topicName 
= FindTopicName(GetNextChunk()); 
1645       int n 
= inFigure 
? figureNo 
: tableNo
; 
1647       AddTexRef(topicName
, NULL
, NULL
, 
1648            ((DocumentStyle 
!= LATEX_ARTICLE
) ? chapterNo 
: n
), 
1649             ((DocumentStyle 
!= LATEX_ARTICLE
) ? n 
: 0)); 
1655     if (start
) TexOutput("ß"); 
1660     if (start
) inFigure 
= TRUE
; 
1661     else inFigure 
= FALSE
; 
1666     if (start
) inTable 
= TRUE
; 
1667     else inTable 
= FALSE
; 
1671     DefaultOnMacro(macroId
, no_args
, start
); 
1676 // Called on start/end of argument examination 
1677 bool HTMLOnArgument(int macroId
, int arg_no
, bool start
) 
1683   case ltCHAPTERHEADING
: 
1686   case ltSECTIONHEADING
: 
1688   case ltSUBSECTIONSTAR
: 
1689   case ltSUBSUBSECTION
: 
1690   case ltSUBSUBSECTIONSTAR
: 
1692   case ltMEMBERSECTION
: 
1693   case ltFUNCTIONSECTION
: 
1695     if (!start 
&& (arg_no 
== 1)) 
1696       currentSection 
= GetArgChunk(); 
1702     if (start 
&& (arg_no 
== 1)) 
1705     if (!start 
&& (arg_no 
== 1)) 
1708     if (start 
&& (arg_no 
== 2)) 
1710       if (!suppressNameDecoration
) TexOutput("<B>"); 
1711       currentMember 
= GetArgChunk(); 
1713     if (!start 
&& (arg_no 
== 2)) 
1715       if (!suppressNameDecoration
) TexOutput("</B>"); 
1718     if (start 
&& (arg_no 
== 3)) 
1720     if (!start 
&& (arg_no 
== 3)) 
1726     if (start 
&& (arg_no 
== 1)) 
1728     if (!start 
&& (arg_no 
== 1)) 
1731     if (start 
&& (arg_no 
== 2)) 
1733       if (!suppressNameDecoration
) TexOutput("( "); 
1734       currentMember 
= GetArgChunk(); 
1736     if (!start 
&& (arg_no 
== 2)) 
1740     if (!start 
&& (arg_no 
== 3)) 
1746     if (!start 
&& (arg_no 
== 1)) 
1749     if (start 
&& (arg_no 
== 2)) 
1751     if (!start 
&& (arg_no 
== 2)) 
1754     if (start 
&& (arg_no 
== 2)) 
1755       currentMember 
= GetArgChunk(); 
1757     if (start 
&& (arg_no 
== 3)) 
1759     if (!start 
&& (arg_no 
== 3)) 
1765     if (start 
&& (arg_no 
== 1)) 
1767     if (!start 
&& (arg_no 
== 1)) 
1769     if (start 
&& (arg_no 
== 2)) 
1773     if (!start 
&& (arg_no 
== 2)) 
1781     if (start 
&& (arg_no 
== 1)) 
1783     if (!start 
&& (arg_no 
== 1)) 
1784       TexOutput("</B> ");  // This is the difference from param - one space! 
1785     if (start 
&& (arg_no 
== 2)) 
1789     if (!start 
&& (arg_no 
== 2)) 
1797     if (!start 
&& (arg_no 
== 1)) 
1800     if (start 
&& (arg_no 
== 2)) 
1801       currentMember 
= GetArgChunk(); 
1810       char *refName 
= GetArgData(); 
1813         TexRef 
*texRef 
= FindReference(refName
); 
1816           sec 
= texRef
->sectionNumber
; 
1829     if (IsArgOptional()) 
1831     else if ((GetNoArgs() - arg_no
) == 1) 
1834         helpRefText 
= GetArgChunk(); 
1837     else if ((GetNoArgs() - arg_no
) == 0) // Arg = 2, or 3 if first is optional 
1841         TexChunk 
*ref 
= GetArgChunk(); 
1842         TexOutput("<A HREF=\""); 
1844         TraverseChildrenFromChunk(ref
); 
1848           TraverseChildrenFromChunk(helpRefText
); 
1859     if (IsArgOptional()) 
1862         helpRefFilename 
= GetArgChunk(); 
1865     if ((GetNoArgs() - arg_no
) == 1) 
1868         helpRefText 
= GetArgChunk(); 
1871     else if ((GetNoArgs() - arg_no
) == 0) // Arg = 2, or 3 if first is optional 
1875         char *refName 
= GetArgData(); 
1876         char *refFilename 
= NULL
; 
1880           TexRef 
*texRef 
= FindReference(refName
); 
1883             if (texRef
->refFile 
&& strcmp(texRef
->refFile
, "??") != 0) 
1884               refFilename 
= texRef
->refFile
; 
1886             TexOutput("<A HREF=\""); 
1887             // If a filename is supplied, use it, otherwise try to 
1888             // use the filename associated with the reference (from this document). 
1889             if (helpRefFilename
) 
1891               TraverseChildrenFromChunk(helpRefFilename
); 
1894             else if (refFilename
) 
1896               TexOutput(ConvertCase(refFilename
)); 
1902               TraverseChildrenFromChunk(helpRefText
); 
1908               TraverseChildrenFromChunk(helpRefText
); 
1909             TexOutput(" (REF NOT FOUND)"); 
1912         else TexOutput("??"); 
1927         char *alignment 
= ""; 
1928         if (macroId 
== ltIMAGEL
) 
1929           alignment 
= " align=left"; 
1930         else if  (macroId 
== ltIMAGER
) 
1931           alignment 
= " align=right"; 
1933         // Try to find an XBM or GIF image first. 
1934         char *filename 
= copystring(GetArgData()); 
1937         strcpy(buf
, filename
); 
1938         StripExtension(buf
); 
1939         strcat(buf
, ".xbm"); 
1940         wxString f 
= TexPathList
.FindValidPath(buf
); 
1942         if (f 
== "") // Try for a GIF instead 
1944           strcpy(buf
, filename
); 
1945           StripExtension(buf
); 
1946           strcat(buf
, ".gif"); 
1947           f 
= TexPathList
.FindValidPath(buf
); 
1950         if (f 
== "") // Try for a JPEG instead 
1952           strcpy(buf
, filename
); 
1953           StripExtension(buf
); 
1954           strcat(buf
, ".jpg"); 
1955           f 
= TexPathList
.FindValidPath(buf
); 
1958         if (f 
== "") // Try for a PNG instead 
1960           strcpy(buf
, filename
); 
1961           StripExtension(buf
); 
1962           strcat(buf
, ".png"); 
1963           f 
= TexPathList
.FindValidPath(buf
); 
1968           char *inlineFilename 
= copystring(f
); 
1970           char *originalFilename 
= TexPathList
.FindValidPath(filename
); 
1971           // If we have found the existing filename, make the inline 
1972           // image point to the original file (could be PS, for example) 
1973           if (originalFilename 
&& (strcmp(inlineFilename
, originalFilename
) != 0)) 
1975             TexOutput("<A HREF=\""); 
1976             TexOutput(ConvertCase(originalFilename
)); 
1978             TexOutput("<img src=\""); 
1979             TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename
))); 
1980             TexOutput("\""); TexOutput(alignment
); TexOutput("></A>"); 
1985             TexOutput("<img src=\""); 
1986             TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename
))); 
1987             TexOutput("\""); TexOutput(alignment
); TexOutput("></A>"); 
1988             delete[] inlineFilename
; 
1993           // Last resort - a link to a PS file. 
1994           TexOutput("<A HREF=\""); 
1995           TexOutput(ConvertCase(wxFileNameFromPath(filename
))); 
1996           TexOutput("\">Picture</A>\n"); 
1997           sprintf(buf
, "Warning: could not find an inline XBM/GIF for %s.", filename
); 
2005   // First arg is PSBOX spec (ignored), second is image file, third is map name. 
2008     static char *imageFile 
= NULL
; 
2009     if (start 
&& (arg_no 
== 2)) 
2011       // Try to find an XBM or GIF image first. 
2012       char *filename 
= copystring(GetArgData()); 
2015       strcpy(buf
, filename
); 
2016       StripExtension(buf
); 
2017       strcat(buf
, ".xbm"); 
2018       wxString f 
= TexPathList
.FindValidPath(buf
); 
2020       if (f 
== "") // Try for a GIF instead 
2022         strcpy(buf
, filename
); 
2023         StripExtension(buf
); 
2024         strcat(buf
, ".gif"); 
2025         f 
= TexPathList
.FindValidPath(buf
); 
2030         sprintf(buf
, "Warning: could not find an inline XBM/GIF for %s.", filename
); 
2039         imageFile 
= copystring(f
); 
2042     else if (start 
&& (arg_no 
== 3)) 
2046         // First, try to find a .shg (segmented hypergraphics file) 
2047         // that we can convert to a map file 
2049         strcpy(buf
, imageFile
); 
2050         StripExtension(buf
); 
2051         strcat(buf
, ".shg"); 
2052         wxString f 
= TexPathList
.FindValidPath(buf
); 
2056           // The default HTML file to go to is THIS file (so a no-op) 
2057           SHGToMap((char*) (const char*) f
, currentFileName
); 
2060         char *mapName 
= GetArgData(); 
2061         TexOutput("<A HREF=\"/cgi-bin/imagemap/"); 
2065           TexOutput("unknown"); 
2067         TexOutput("<img src=\""); 
2068         TexOutput(ConvertCase(wxFileNameFromPath(imageFile
))); 
2069         TexOutput("\" ISMAP></A><P>"); 
2090       descriptionItemArg 
= GetArgChunk(); 
2095   case ltTWOCOLITEMRULED
: 
2098     if (start && (arg_no == 1)) 
2099       TexOutput("\n<DT> "); 
2100     if (start && (arg_no == 2)) 
2107         if (TwoColWidthA 
> -1) { 
2109           sprintf(buf
,"\n<TR><TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthA
); 
2112           TexOutput("\n<TR><TD VALIGN=TOP>\n"); 
2114             TexOutput("\n</TD>\n"); 
2120         if (TwoColWidthB 
> -1) { 
2122           sprintf(buf
,"\n<TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthB
); 
2125            TexOutput("\n<TD VALIGN=TOP>\n"); 
2127            TexOutput("\n</TD></TR>\n"); 
2132   case ltNUMBEREDBIBITEM
: 
2134     if (arg_no 
== 1 && start
) 
2136       TexOutput("\n<DT> "); 
2138     if (arg_no 
== 2 && !start
) 
2145     if (arg_no 
== 1 && start
) 
2147       char *citeKey 
= GetArgData(); 
2148       TexRef 
*ref 
= (TexRef 
*)TexReferences
.Get(citeKey
); 
2151         if (ref
->sectionNumber
) delete[] ref
->sectionNumber
; 
2152         sprintf(buf
, "[%d]", citeCount
); 
2153         ref
->sectionNumber 
= copystring(buf
); 
2156       sprintf(buf
, "\n<DT> [%d] ", citeCount
); 
2161     if (arg_no 
== 2 && !start
) 
2167   case ltMARGINPARODD
: 
2168   case ltMARGINPAREVEN
: 
2174       TexOutput("<HR>\n"); 
2178       TexOutput("<HR><P>\n"); 
2182   case ltTWOCOLWIDTHA
: 
2186       char *val 
= GetArgData(); 
2187       float points 
= ParseUnitArgument(val
); 
2188       TwoColWidthA 
= (int)((points 
* 100.0) / 72.0); 
2194   case ltTWOCOLWIDTHB
: 
2198       char *val 
= GetArgData(); 
2199       float points 
= ParseUnitArgument(val
); 
2200       TwoColWidthB 
= (int)((points 
* 100.0) / 72.0); 
2209   case ltACCENT_GRAVE
: 
2213       char *val 
= GetArgData(); 
2219            TexOutput("à"); 
2222            TexOutput("è"); 
2225            TexOutput("ì"); 
2228            TexOutput("ò"); 
2231            TexOutput("ù"); 
2234            TexOutput("À"); 
2237            TexOutput("È"); 
2240            TexOutput("Ì"); 
2243            TexOutput("Ò"); 
2246            TexOutput("Ì"); 
2256   case ltACCENT_ACUTE
: 
2260       char *val 
= GetArgData(); 
2266            TexOutput("á"); 
2269            TexOutput("é"); 
2272            TexOutput("í"); 
2275            TexOutput("ó"); 
2278            TexOutput("ú"); 
2281            TexOutput("ý"); 
2284            TexOutput("Á"); 
2287            TexOutput("É"); 
2290            TexOutput("Í"); 
2293            TexOutput("Ó"); 
2296            TexOutput("Ú"); 
2299            TexOutput("Ý"); 
2309   case ltACCENT_CARET
: 
2313       char *val 
= GetArgData(); 
2319            TexOutput("â"); 
2322            TexOutput("ê"); 
2325            TexOutput("î"); 
2328            TexOutput("ô"); 
2331            TexOutput("û"); 
2334            TexOutput("Â"); 
2337            TexOutput("Ê"); 
2340            TexOutput("Î"); 
2343            TexOutput("Ô"); 
2346            TexOutput("Î"); 
2356   case ltACCENT_TILDE
: 
2360       char *val 
= GetArgData(); 
2369            TexOutput("ã"); 
2372            TexOutput("ñ"); 
2375            TexOutput("õ"); 
2378            TexOutput("Ã"); 
2381            TexOutput("Ñ"); 
2384            TexOutput("Õ"); 
2394   case ltACCENT_UMLAUT
: 
2398       char *val 
= GetArgData(); 
2404            TexOutput("ä"); 
2407            TexOutput("ë"); 
2410            TexOutput("ï"); 
2413            TexOutput("ö"); 
2416            TexOutput("ü"); 
2419            TexOutput("ÿ"); 
2422            TexOutput("Ä"); 
2425            TexOutput("Ë"); 
2428            TexOutput("Ï"); 
2431            TexOutput("Ö"); 
2434            TexOutput("Ü"); 
2437            TexOutput("Ÿ"); 
2451       char *val 
= GetArgData(); 
2457            TexOutput("å"); 
2460            TexOutput("Å"); 
2474       char *val 
= GetArgData(); 
2477         bool isPicture 
= FALSE
; 
2478         char *s 
= ParseColourString(val
, &isPicture
); 
2481           if (backgroundImageString
) 
2482             delete[] backgroundImageString
; 
2483           backgroundImageString 
= copystring(val
); 
2487           if (backgroundColourString
) 
2488             delete[] backgroundColourString
; 
2489           backgroundColourString 
= copystring(val
); 
2496   case ltBACKGROUNDIMAGE
: 
2500       char *val 
= GetArgData(); 
2503         if (backgroundImageString
) 
2504           delete[] backgroundImageString
; 
2505         backgroundImageString 
= copystring(val
); 
2511   case ltBACKGROUNDCOLOUR
: 
2515       char *val 
= GetArgData(); 
2518         if (backgroundColourString
) 
2519           delete[] backgroundColourString
; 
2520         backgroundColourString 
= copystring(val
); 
2530       char *val 
= GetArgData(); 
2533         if (textColourString
) 
2534           delete[] textColourString
; 
2535         textColourString 
= copystring(val
); 
2545       char *val 
= GetArgData(); 
2548         if (linkColourString
) 
2549           delete[] linkColourString
; 
2550         linkColourString 
= copystring(val
); 
2556   case ltFOLLOWEDLINKCOLOUR
: 
2560       char *val 
= GetArgData(); 
2563         if (followedLinkColourString
) 
2564           delete[] followedLinkColourString
; 
2565         followedLinkColourString 
= copystring(val
); 
2571   case ltACCENT_CADILLA
: 
2575       char *val 
= GetArgData(); 
2581            TexOutput("ç"); 
2584            TexOutput("Ç"); 
2596   case ltFOOTNOTEPOPUP: 
2606   case ltSUPERTABULAR
: 
2612         currentRowNumber 
= 0; 
2615         tableVerticalLineLeft 
= FALSE
; 
2616         tableVerticalLineRight 
= FALSE
; 
2617         int currentWidth 
= 0; 
2619         char *alignString 
= copystring(GetArgData()); 
2620         ParseTableArgument(alignString
); 
2622         TexOutput("<TABLE BORDER>\n"); 
2624         // Write the first row formatting for compatibility 
2625         // with standard Latex 
2626         if (compatibilityMode
) 
2628           TexOutput("<TR>\n<TD>"); 
2630           for (int i = 0; i < noColumns; i++) 
2632             currentWidth += TableData[i].width; 
2633             sprintf(buf, "\\cellx%d", currentWidth); 
2636           TexOutput("\\pard\\intbl\n"); 
2639         delete[] alignString
; 
2644     else if (arg_no 
== 2 && !start
) 
2646       TexOutput("</TABLE>\n"); 
2651   case ltTHEBIBLIOGRAPHY
: 
2653     if (start 
&& (arg_no 
== 1)) 
2655       ReopenFile(&Chapters
, &ChaptersName
); 
2656       AddTexRef("bibliography", ChaptersName
, "bibliography"); 
2657       SetCurrentSubsectionName("bibliography", ChaptersName
); 
2661       SetCurrentOutput(Chapters
); 
2664       if (truncateFilenames
) 
2665         sprintf(titleBuf
, "%s.htm", FileNameFromPath(FileRoot
)); 
2667         sprintf(titleBuf
, "%s_contents.html", FileNameFromPath(FileRoot
)); 
2669       TexOutput("<head><title>"); 
2670       TexOutput(ReferencesNameString
); 
2671       TexOutput("</title></head>\n"); 
2674       fprintf(Chapters
, "<A NAME=\"%s\">\n<H2>%s", "bibliography", ReferencesNameString
); 
2675       AddBrowseButtons("contents", titleBuf
, // Up 
2676                        lastTopic
, lastFileName
,  // Last topic 
2677                        "bibliography", ChaptersName
); // This topic 
2679       SetCurrentOutputs(Contents
, Chapters
); 
2680       fprintf(Contents
, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName
), "bibliography"); 
2682       fprintf(Contents
, "%s</A>\n", ReferencesNameString
); 
2683       fprintf(Chapters
, "</H2>\n</A>\n"); 
2685       SetCurrentOutput(Chapters
); 
2688     if (!start 
&& (arg_no 
== 2)) 
2696     /* Build up list of keywords associated with topics */ 
2699 //      char *entry = GetArgData(); 
2701       OutputChunkToString(GetArgChunk(), buf
); 
2704         AddKeyWordForTopic(CurrentTopic
, buf
, currentFileName
); 
2719           char *name 
= GetArgData(); 
2721           if (!FindColourHTMLString(name
, buf2
)) 
2723             strcpy(buf2
, "#000000"); 
2725                         sprintf(buf
, "Could not find colour name %s", name
); 
2728           TexOutput("<FONT COLOR=\""); 
2744       if (arg_no 
== 2) TexOutput("</FONT>"); 
2749   case ltINSERTATLEVEL
: 
2751     // This macro allows you to insert text at a different level 
2752     // from the current level, e.g. into the Sections from within a subsubsection. 
2755     static int currentLevelNo 
= 1; 
2756     static FILE* oldLevelFile 
= Chapters
; 
2763           oldLevelFile 
= CurrentOutput1
; 
2765           char *str 
= GetArgData(); 
2766           currentLevelNo 
= atoi(str
); 
2768           // TODO: cope with article style (no chapters) 
2769           switch (currentLevelNo
) 
2773                 outputFile 
= Chapters
; 
2778                 outputFile 
= Sections
; 
2783                 outputFile 
= Subsections
; 
2788                 outputFile 
= Subsubsections
; 
2798             CurrentOutput1 
= outputFile
; 
2816             CurrentOutput1 
= oldLevelFile
; 
2822     return DefaultOnArgument(macroId
, arg_no
, start
); 
2835   tableVerticalLineLeft 
= FALSE
; 
2836   tableVerticalLineRight 
= FALSE
; 
2839   if (InputFile 
&& OutputFile
) 
2841     // Do some HTML-specific transformations on all the strings, 
2843     Text2HTML(GetTopLevelChunk()); 
2846     if (truncateFilenames
) 
2847       sprintf(buf
, "%s.htm", FileRoot
); 
2849       sprintf(buf
, "%s_contents.html", FileRoot
); 
2850     if (TitlepageName
) delete[] TitlepageName
; 
2851     TitlepageName 
= copystring(buf
); 
2852     Titlepage 
= fopen(buf
, "w"); 
2854     if (truncateFilenames
) 
2855       sprintf(buf
, "%s_fc.htm", FileRoot
); 
2857       sprintf(buf
, "%s_fcontents.html", FileRoot
); 
2859     contentsFrameName 
= copystring(buf
); 
2861     Contents 
= fopen(TmpContentsName
, "w"); 
2863     if (htmlFrameContents
) 
2865 //      FrameContents = fopen(TmpFrameContentsName, "w"); 
2866       FrameContents 
= fopen(contentsFrameName
, "w"); 
2867       fprintf(FrameContents
, "<HTML>\n<UL>\n"); 
2870     if (!Titlepage 
|| !Contents
) 
2872       OnError("Cannot open output file!"); 
2875     AddTexRef("contents", FileNameFromPath(TitlepageName
), ContentsNameString
); 
2877     fprintf(Contents
, "<P><P><H2>%s</H2><P><P>\n", ContentsNameString
); 
2879     fprintf(Contents
, "<UL>\n"); 
2881     SetCurrentOutput(Titlepage
); 
2882     if (htmlWorkshopFiles
) HTMLWorkshopStartContents(); 
2883     OnInform("Converting..."); 
2886     fprintf(Contents
, "</UL>\n\n"); 
2888 //    SetCurrentOutput(Titlepage); 
2893 //      fprintf(Titlepage, "\n</BODY></HTML>\n"); 
2900       fprintf(FrameContents
, "\n</UL>\n"); 
2901       fprintf(FrameContents
, "</HTML>\n"); 
2902       fclose(FrameContents
); 
2903       FrameContents 
= NULL
; 
2908       fprintf(Chapters
, "\n</BODY></HTML>\n"); 
2914       fprintf(Sections
, "\n</BODY></HTML>\n"); 
2918     if (Subsections 
&& !combineSubSections
) 
2920       fprintf(Subsections
, "\n</BODY></HTML>\n"); 
2921       fclose(Subsections
); 
2924     if (Subsubsections 
&& !combineSubSections
) 
2926       fprintf(Subsubsections
, "\n</BODY></HTML>\n"); 
2927       fclose(Subsubsections
); 
2928       Subsubsections 
= NULL
; 
2930     if ( SectionContentsFD 
) 
2932         fclose(SectionContentsFD
); 
2933         SectionContentsFD 
= NULL
; 
2936     // Create a temporary file for the title page header, add some info, 
2937     // and concat the titlepage just generated. 
2938     // This is necessary in order to put the title of the document 
2939     // at the TOP of the file within <HEAD>, even though we only find out 
2940     // what it is later on. 
2941     FILE *tmpTitle 
= fopen("title.tmp", "w"); 
2946         SetCurrentOutput(tmpTitle
); 
2947         TexOutput("\n<HTML>\n<HEAD><TITLE>"); 
2948         TraverseChildrenFromChunk(DocumentTitle
); 
2949         TexOutput("</TITLE></HEAD>\n"); 
2953         SetCurrentOutput(tmpTitle
); 
2955           fprintf(tmpTitle
, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", contentsString
); 
2957           fprintf(tmpTitle
, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", FileNameFromPath(FileRoot
)); 
2960       // Output frame information 
2961       if (htmlFrameContents
) 
2963         char firstFileName
[300]; 
2964         if (truncateFilenames
) 
2965           sprintf(firstFileName
, "%s1.htm", FileRoot
); 
2967           sprintf(firstFileName
, "%s1.html", FileRoot
); 
2969         fprintf(tmpTitle
, "<FRAMESET COLS=\"30%%,70%%\">\n"); 
2971         fprintf(tmpTitle
, "<FRAME SRC=\"%s\">\n", ConvertCase(FileNameFromPath(contentsFrameName
))); 
2972         fprintf(tmpTitle
, "<FRAME SRC=\"%s\" NAME=\"mainwindow\">\n", ConvertCase(FileNameFromPath(firstFileName
))); 
2973         fprintf(tmpTitle
, "</FRAMESET>\n"); 
2975         fprintf(tmpTitle
, "<NOFRAMES>\n"); 
2978       // Output <BODY...> to temporary title page 
2982       FILE *fd 
= fopen(TitlepageName
, "r"); 
2994       fprintf(tmpTitle
, "\n</BODY>\n"); 
2996       if (htmlFrameContents
) 
2998         fprintf(tmpTitle
, "\n</NOFRAMES>\n"); 
3000       fprintf(tmpTitle
, "\n</HTML>\n"); 
3003       if (FileExists(TitlepageName
)) wxRemoveFile(TitlepageName
); 
3004       if (!wxRenameFile("title.tmp", TitlepageName
)) 
3006         wxCopyFile("title.tmp", TitlepageName
); 
3007         wxRemoveFile("title.tmp"); 
3011     if (lastFileName
) delete[] lastFileName
; 
3012     lastFileName 
= NULL
; 
3013     if (lastTopic
) delete[] lastTopic
; 
3016     if (FileExists(ContentsName
)) wxRemoveFile(ContentsName
); 
3018     if (!wxRenameFile(TmpContentsName
, ContentsName
)) 
3020       wxCopyFile(TmpContentsName
, ContentsName
); 
3021       wxRemoveFile(TmpContentsName
); 
3024     // Generate .htx file if requested 
3027       char htmlIndexName
[300]; 
3028       sprintf(htmlIndexName
, "%s.htx", FileRoot
); 
3029       GenerateHTMLIndexFile(htmlIndexName
); 
3032     // Generate HTML Help Workshop files if requested 
3033     if (htmlWorkshopFiles
) 
3035       HTMLWorkshopEndContents(); 
3036       GenerateHTMLWorkshopFiles(FileRoot
); 
3046 // Output .htx index file 
3047 void GenerateHTMLIndexFile(char *fname
) 
3049   FILE *fd 
= fopen(fname
, "w"); 
3053   TopicTable
.BeginFind(); 
3054   wxNode 
*node 
= NULL
; 
3055   while ((node 
= TopicTable
.Next())) 
3057     TexTopic 
*texTopic 
= (TexTopic 
*)node
->Data(); 
3058     const char *topicName 
= node
->GetKeyString(); 
3059     if (texTopic
->filename 
&& texTopic
->keywords
) 
3061       wxNode 
*node1 
= texTopic
->keywords
->First(); 
3064         char *s 
= (char *)node1
->Data(); 
3065         fprintf(fd
, "%s|%s|%s\n", topicName
, texTopic
->filename
, s
); 
3066         node1 
= node1
->Next(); 
3079 // output .hpp, .hhc and .hhk files: 
3082 void GenerateHTMLWorkshopFiles(char *fname
) 
3087   /* Generate project file : */ 
3089   sprintf(buf
, "%s.hhp", fname
); 
3090   f 
= fopen(buf
, "wt"); 
3093       "Compatibility=1.1\n" 
3094       "Full-text search=Yes\n" 
3095       "Contents file=%s.hhc\n" 
3096       "Compiled file=%s.chm\n" 
3097       "Default Window=%sHelp\n" 
3098       "Default topic=%s\n" 
3099       "Index file=%s.hhk\n" 
3101       FileNameFromPath(fname
), 
3102       FileNameFromPath(fname
), 
3103       FileNameFromPath(fname
), 
3104       FileNameFromPath(TitlepageName
), 
3105       FileNameFromPath(fname
) 
3108   if (DocumentTitle
) { 
3109     SetCurrentOutput(f
); 
3110     TraverseChildrenFromChunk(DocumentTitle
); 
3112   else fprintf(f
, "(unknown)"); 
3114   fprintf(f
, "\n\n[WINDOWS]\n" 
3115           "%sHelp=,\"%s.hhc\",\"%s.hhk\",\"%s\",,,,,,0x2420,,0x380e,,,,,0,,,", 
3116           FileNameFromPath(fname
), 
3117           FileNameFromPath(fname
), 
3118           FileNameFromPath(fname
), 
3119           FileNameFromPath(TitlepageName
)); 
3122   fprintf(f
, "\n\n[FILES]\n"); 
3123   fprintf(f
, "%s\n", FileNameFromPath(TitlepageName
)); 
3124   for (int i 
= 1; i 
<= fileId
; i
++) { 
3125     if (truncateFilenames
) 
3126       sprintf(buf
, "%s%d.htm", FileNameFromPath(FileRoot
), i
); 
3128       sprintf(buf
, "%s%d.html", FileNameFromPath(FileRoot
), i
); 
3129     fprintf(f
, "%s\n", buf
); 
3133   /* Generate index file : */ 
3135   sprintf(buf
, "%s.hhk", fname
); 
3136   f 
= fopen(buf
, "wt"); 
3139       "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n" 
3142       "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n" 
3143       "<!-- Sitemap 1.0 -->\n" 
3145       "<OBJECT type=\"text/site properties\">\n" 
3146       " <param name=\"ImageType\" value=\"Folder\">\n" 
3150   TopicTable
.BeginFind(); 
3151   wxNode 
*node 
= NULL
; 
3152   while ((node 
= TopicTable
.Next())) 
3154     TexTopic 
*texTopic 
= (TexTopic 
*)node
->Data(); 
3155     const char *topicName 
= node
->GetKeyString(); 
3156     if (texTopic
->filename 
&& texTopic
->keywords
) 
3158       wxNode 
*node1 
= texTopic
->keywords
->First(); 
3161         char *s 
= (char *)node1
->Data(); 
3163             " <LI> <OBJECT type=\"text/sitemap\">\n" 
3164             "  <param name=\"Local\" value=\"%s#%s\">\n" 
3165             "  <param name=\"Name\" value=\"%s\">\n" 
3167             texTopic
->filename
, topicName
, s
); 
3168         node1 
= node1
->Next(); 
3173   fprintf(f
, "</UL>\n"); 
3179 static FILE *HTMLWorkshopContents 
= NULL
; 
3180 static int HTMLWorkshopLastLevel 
= 0; 
3182 void HTMLWorkshopAddToContents(int level
, char *s
, char *file
) 
3186   if (level 
> HTMLWorkshopLastLevel
) 
3187     for (i 
= HTMLWorkshopLastLevel
; i 
< level
; i
++) 
3188       fprintf(HTMLWorkshopContents
, "<UL>"); 
3189   if (level 
< HTMLWorkshopLastLevel
) 
3190     for (i 
= level
; i 
< HTMLWorkshopLastLevel
; i
++) 
3191       fprintf(HTMLWorkshopContents
, "</UL>"); 
3193   SetCurrentOutput(HTMLWorkshopContents
); 
3194   fprintf(HTMLWorkshopContents
, 
3195             " <LI> <OBJECT type=\"text/sitemap\">\n" 
3196             "  <param name=\"Local\" value=\"%s#%s\">\n" 
3197             "  <param name=\"Name\" value=\"", 
3199   OutputCurrentSection(); 
3200   fprintf(HTMLWorkshopContents
, 
3203   HTMLWorkshopLastLevel 
= level
; 
3207 void HTMLWorkshopStartContents() 
3210   sprintf(buf
, "%s.hhc", FileRoot
); 
3211   HTMLWorkshopContents 
= fopen(buf
, "wt"); 
3212   HTMLWorkshopLastLevel 
= 0; 
3214   fprintf(HTMLWorkshopContents
, 
3215       "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n" 
3218       "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n" 
3219       "<!-- Sitemap 1.0 -->\n" 
3221       "<OBJECT type=\"text/site properties\">\n" 
3222       " <param name=\"ImageType\" value=\"Folder\">\n" 
3225       "<LI> <OBJECT type=\"text/sitemap\">\n" 
3226       "<param name=\"Local\" value=\"%s\">\n" 
3227       "<param name=\"Name\" value=\"Contents\">\n</OBJECT>\n", 
3228       FileNameFromPath(TitlepageName
) 
3234 void HTMLWorkshopEndContents() 
3236   for (int i 
= HTMLWorkshopLastLevel
; i 
>= 0; i
--) 
3237     fprintf(HTMLWorkshopContents
, "</UL>\n"); 
3238   fclose(HTMLWorkshopContents
);