///////////////////////////////////////////////////////////////////////////// // Name: htmlutil.cpp // Purpose: Converts Latex to HTML // Author: Julian Smart // Modified by: // Created: 7.9.93 // RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "tex2any.h" #include "tex2rtf.h" #include "table.h" extern wxHashTable TexReferences; extern void DecToHex(int, char *); void GenerateHTMLIndexFile(char *fname); void GenerateHTMLWorkshopFiles(char *fname); void HTMLWorkshopAddToContents(int level, char *s, char *file); void HTMLWorkshopStartContents(); void HTMLWorkshopEndContents(); void OutputContentsFrame(void); #include "readshg.h" // Segmented hypergraphics parsing char *ChaptersName = NULL; char *SectionsName = NULL; char *SubsectionsName = NULL; char *SubsubsectionsName = NULL; char *TitlepageName = NULL; char *lastFileName = NULL; char *lastTopic = NULL; char *currentFileName = NULL; char *contentsFrameName = NULL; static TexChunk *descriptionItemArg = NULL; static TexChunk *helpRefFilename = NULL; static TexChunk *helpRefText = NULL; static int indentLevel = 0; static int citeCount = 1; extern FILE *Contents; FILE *FrameContents = NULL; FILE *Titlepage = NULL; // FILE *FrameTitlepage = NULL; int fileId = 0; bool subsectionStarted = FALSE; // Which column of a row are we in? (Assumes no nested tables, of course) int currentColumn = 0; // Are we in verbatim mode? If so, format differently. static bool inVerbatim = FALSE; // Need to know whether we're in a table or figure for benefit // of listoffigures/listoftables static bool inFigure = FALSE; static bool inTable = FALSE; // This is defined in the Tex2Any library. extern char *BigBuffer; // DHS Two-column table dimensions. static int TwoColWidthA = -1; static int TwoColWidthB = -1; class HyperReference: public wxObject { public: char *refName; char *refFile; HyperReference(char *name, char *file) { if (name) refName = copystring(name); if (file) refFile = copystring(file); } }; class TexNextPage: public wxObject { public: char *label; char *filename; TexNextPage(char *theLabel, char *theFile) { label = copystring(theLabel); filename = copystring(theFile); } ~TexNextPage(void) { delete[] label; delete[] filename; } }; wxHashTable TexNextPages(wxKEY_STRING); static char *CurrentChapterName = NULL; static char *CurrentChapterFile = NULL; static char *CurrentSectionName = NULL; static char *CurrentSectionFile = NULL; static char *CurrentSubsectionName = NULL; static char *CurrentSubsectionFile = NULL; static char *CurrentSubsubsectionName = NULL; static char *CurrentSubsubsectionFile = NULL; static char *CurrentTopic = NULL; static void SetCurrentTopic(char *s) { if (CurrentTopic) delete[] CurrentTopic; CurrentTopic = copystring(s); } void SetCurrentChapterName(char *s, char *file) { if (CurrentChapterName) delete[] CurrentChapterName; CurrentChapterName = copystring(s); if (CurrentChapterFile) delete[] CurrentChapterFile; CurrentChapterFile = copystring(file); currentFileName = CurrentChapterFile; SetCurrentTopic(s); } void SetCurrentSectionName(char *s, char *file) { if (CurrentSectionName) delete[] CurrentSectionName; CurrentSectionName = copystring(s); if (CurrentSectionFile) delete[] CurrentSectionFile; CurrentSectionFile = copystring(file); currentFileName = CurrentSectionFile; SetCurrentTopic(s); } void SetCurrentSubsectionName(char *s, char *file) { if (CurrentSubsectionName) delete[] CurrentSubsectionName; CurrentSubsectionName = copystring(s); if (CurrentSubsectionFile) delete[] CurrentSubsectionFile; CurrentSubsectionFile = copystring(file); currentFileName = CurrentSubsectionFile; SetCurrentTopic(s); } void SetCurrentSubsubsectionName(char *s, char *file) { if (CurrentSubsubsectionName) delete[] CurrentSubsubsectionName; CurrentSubsubsectionName = copystring(s); if (CurrentSubsubsectionFile) delete[] CurrentSubsubsectionFile; CurrentSubsubsectionFile = copystring(file); currentFileName = CurrentSubsubsectionFile; SetCurrentTopic(s); } /* * Close former filedescriptor and reopen using another filename. * */ void ReopenFile(FILE **fd, char **fileName) { if (*fd) { fprintf(*fd, "\n\n"); fclose(*fd); } fileId ++; char buf[400]; if (truncateFilenames) sprintf(buf, "%s%d.htm", FileRoot, fileId); else sprintf(buf, "%s%d.html", FileRoot, fileId); if (*fileName) delete[] *fileName; *fileName = copystring(FileNameFromPath(buf)); *fd = fopen(buf, "w"); fprintf(*fd, "\n"); } /* * Reopen section contents file, i.e. the index appended to each section * in subsectionCombine mode */ static char *SectionContentsFilename = NULL; static FILE *SectionContentsFD = NULL; void ReopenSectionContentsFile(void) { if ( SectionContentsFD ) { fclose(SectionContentsFD); } if ( SectionContentsFilename ) delete[] SectionContentsFilename; SectionContentsFD = NULL; SectionContentsFilename = NULL; // Create the name from the current section filename if ( CurrentSectionFile ) { char buf[256]; strcpy(buf, CurrentSectionFile); wxStripExtension(buf); strcat(buf, ".con"); SectionContentsFilename = copystring(buf); SectionContentsFD = fopen(SectionContentsFilename, "w"); } } /* * Given a TexChunk with a string value, scans through the string * converting Latex-isms into HTML-isms, such as 2 newlines ->

. * */ void ProcessText2HTML(TexChunk *chunk) { bool changed = FALSE; int ptr = 0; int i = 0; char ch = 1; int len = strlen(chunk->value); while (ch != 0) { ch = chunk->value[i]; // 2 newlines means \par if (!inVerbatim && chunk->value[i] == 10 && ((len > i+1 && chunk->value[i+1] == 10) || ((len > i+1 && chunk->value[i+1] == 13) && (len > i+2 && chunk->value[i+2] == 10)))) { BigBuffer[ptr] = 0; strcat(BigBuffer, "

\n\n"); ptr += 5; i += 2; changed = TRUE; } else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`')) { BigBuffer[ptr] = '"'; ptr ++; i += 2; changed = TRUE; } else if (!inVerbatim && ch == '`') // Change ` to ' { BigBuffer[ptr] = 39; ptr ++; i += 1; changed = TRUE; } else if (ch == '<') // Change < to < { BigBuffer[ptr] = 0; strcat(BigBuffer, "<"); ptr += 4; i += 1; changed = TRUE; } else if (ch == '>') // Change > to > { BigBuffer[ptr] = 0; strcat(BigBuffer, ">"); ptr += 4; i += 1; changed = TRUE; } else { BigBuffer[ptr] = ch; i ++; ptr ++; } } BigBuffer[ptr] = 0; if (changed) { delete chunk->value; chunk->value = copystring(BigBuffer); } } /* * Scan through all chunks starting from the given one, * calling ProcessText2HTML to convert Latex-isms to RTF-isms. * This should be called after Tex2Any has parsed the file, * and before TraverseDocument is called. * */ void Text2HTML(TexChunk *chunk) { Tex2RTFYield(); if (stopRunning) return; switch (chunk->type) { case CHUNK_TYPE_MACRO: { TexMacroDef *def = chunk->def; if (def && def->ignore) return; if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL)) inVerbatim = TRUE; wxNode *node = chunk->children.First(); while (node) { TexChunk *child_chunk = (TexChunk *)node->Data(); Text2HTML(child_chunk); node = node->Next(); } if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL)) inVerbatim = FALSE; break; } case CHUNK_TYPE_ARG: { wxNode *node = chunk->children.First(); while (node) { TexChunk *child_chunk = (TexChunk *)node->Data(); Text2HTML(child_chunk); node = node->Next(); } break; } case CHUNK_TYPE_STRING: { if (chunk->value) ProcessText2HTML(chunk); break; } } } /* * Add appropriate browse buttons to this page. * */ void AddBrowseButtons(char *upLabel, char *upFilename, char *previousLabel, char *previousFilename, char *thisLabel, char *thisFilename) { char contentsReferenceBuf[80]; char upReferenceBuf[80]; char backReferenceBuf[80]; char forwardReferenceBuf[80]; if (htmlBrowseButtons == HTML_BUTTONS_NONE) return; char *contentsReference = NULL; if (htmlBrowseButtons == HTML_BUTTONS_TEXT) contentsReference = ContentsNameString; else { // contentsReference = "\"Contents\""; contentsReference = contentsReferenceBuf; sprintf(contentsReference, "\"Contents\"", ConvertCase("contents.gif")); } char *upReference = NULL; if (htmlBrowseButtons == HTML_BUTTONS_TEXT) upReference = UpNameString; else { // upReference = "\"Up\""; upReference = upReferenceBuf; sprintf(upReference, "\"Up\"", ConvertCase("up.gif")); } char *backReference = NULL; if (htmlBrowseButtons == HTML_BUTTONS_TEXT) backReference = "<<"; else { // backReference = "\"Previous\""; backReference = backReferenceBuf; sprintf(backReference, "\"Previous\"", ConvertCase("back.gif")); } char *forwardReference = NULL; if (htmlBrowseButtons == HTML_BUTTONS_TEXT) forwardReference = ">>"; else { // forwardReference = "\"Next\""; forwardReference = forwardReferenceBuf; sprintf(forwardReference, "\"Next\"", ConvertCase("forward.gif")); } TexOutput("

"); char buf[200]; /* * Contents button * */ if (truncateFilenames) { char buf1[80]; strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot))); sprintf(buf, "\n%s ", buf1, ConvertCase("htm"), contentsReference); } else { char buf1[80]; strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot))); sprintf(buf, "\n%s ", buf1, ConvertCase("_contents.html"), contentsReference); } // TexOutput(""); TexOutput(buf); // TexOutput(""); /* * Up button * */ if (upLabel && upFilename) { if (strlen(upLabel) > 0) sprintf(buf, "%s ", ConvertCase(upFilename), upLabel, upReference); else sprintf(buf, "%s ", ConvertCase(upFilename), upReference); if (strcmp(upLabel, "contents") == 0) { // TexOutput(""); TexOutput(buf); // TexOutput(""); } else TexOutput(buf); } /* * << button * */ if (previousLabel && previousFilename) { sprintf(buf, "%s ", ConvertCase(previousFilename), previousLabel, backReference); if (strcmp(previousLabel, "contents") == 0) { // TexOutput(""); TexOutput(buf); // TexOutput(""); } else TexOutput(buf); } else { // A placeholder so the buttons don't keep moving position sprintf(buf, "%s ", backReference); TexOutput(buf); } char *nextLabel = NULL; char *nextFilename = NULL; // Get the next page, and record the previous page's 'next' page // (i.e. this page) TexNextPage *nextPage = (TexNextPage *)TexNextPages.Get(thisLabel); if (nextPage) { nextLabel = nextPage->label; nextFilename = nextPage->filename; } if (previousLabel && previousFilename) { TexNextPage *oldNextPage = (TexNextPage *)TexNextPages.Get(previousLabel); if (oldNextPage) { delete oldNextPage; TexNextPages.Delete(previousLabel); } TexNextPage *newNextPage = new TexNextPage(thisLabel, thisFilename); TexNextPages.Put(previousLabel, newNextPage); } /* * >> button * */ if (nextLabel && nextFilename) { sprintf(buf, "%s ", ConvertCase(nextFilename), nextLabel, forwardReference); TexOutput(buf); } else { // A placeholder so the buttons don't keep moving position sprintf(buf, "%s ", forwardReference); TexOutput(buf); } /* * Horizontal rule to finish it off nicely. * */ TexOutput("
"); TexOutput("
\n"); // Update last topic/filename if (lastFileName) delete[] lastFileName; lastFileName = copystring(thisFilename); if (lastTopic) delete[] lastTopic; lastTopic = copystring(thisLabel); } // A colour string is either 3 numbers separated by semicolons (RGB), // or a reference to a GIF. Return the filename or a hex string like #934CE8 char *ParseColourString(char *bkStr, bool *isPicture) { static char resStr[300]; strcpy(resStr, bkStr); char *tok1 = strtok(resStr, ";"); char *tok2 = strtok(NULL, ";"); if (tok1) { if (!tok2) { *isPicture = TRUE; return resStr; } else { *isPicture = FALSE; char *tok3 = strtok(NULL, ";"); if (tok3) { // Now convert 3 strings into decimal numbers, and then hex numbers. int red = atoi(tok1); int green = atoi(tok2); int blue = atoi(tok3); strcpy(resStr, "#"); char buf[3]; DecToHex(red, buf); strcat(resStr, buf); DecToHex(green, buf); strcat(resStr, buf); DecToHex(blue, buf); strcat(resStr, buf); return resStr; } else return NULL; } } else return NULL; } void OutputFont(void) { // Output TexOutput("\n"); } // Output start of block void OutputBodyStart(void) { TexOutput("\n\n"); OutputFont(); } void HTMLHead() { TexOutput(""); if (htmlStylesheet) { TexOutput(""); } }; void HTMLHeadTo(FILE* f) { if (htmlStylesheet) fprintf(f,"",htmlStylesheet); else fprintf(f,""); } // Called on start/end of macro examination void HTMLOnMacro(int macroId, int no_args, bool start) { switch (macroId) { case ltCHAPTER: case ltCHAPTERSTAR: case ltCHAPTERHEADING: { if (!start) { sectionNo = 0; figureNo = 0; subsectionNo = 0; subsubsectionNo = 0; if (macroId != ltCHAPTERSTAR) chapterNo ++; SetCurrentOutput(NULL); startedSections = TRUE; char *topicName = FindTopicName(GetNextChunk()); ReopenFile(&Chapters, &ChaptersName); AddTexRef(topicName, ChaptersName, ChapterNameString); SetCurrentChapterName(topicName, ChaptersName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(0, topicName, ChaptersName); SetCurrentOutput(Chapters); HTMLHead(); TexOutput(""); OutputCurrentSection(); // Repeat section header TexOutput("\n"); OutputBodyStart(); char titleBuf[200]; if (truncateFilenames) sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot)); else sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot)); fprintf(Chapters, "", topicName); AddBrowseButtons("", titleBuf, // Up lastTopic, lastFileName, // Last topic topicName, ChaptersName); // This topic fprintf(Contents, "\n
  • ", ConvertCase(ChaptersName), topicName); if (htmlFrameContents && FrameContents) { SetCurrentOutput(FrameContents); fprintf(FrameContents, "\n
  • ", ConvertCase(ChaptersName), topicName); OutputCurrentSection(); fprintf(FrameContents, "\n"); } SetCurrentOutputs(Contents, Chapters); fprintf(Chapters, "\n

    "); OutputCurrentSection(); fprintf(Contents, "\n"); fprintf(Chapters, "

    \n"); SetCurrentOutput(Chapters); // Add this section title to the list of keywords if (htmlIndex) { OutputCurrentSectionToString(wxTex2RTFBuffer); AddKeyWordForTopic(topicName, wxTex2RTFBuffer, ConvertCase(currentFileName)); } } break; } case ltSECTION: case ltSECTIONSTAR: case ltSECTIONHEADING: case ltGLOSS: { if (!start) { subsectionNo = 0; subsubsectionNo = 0; subsectionStarted = FALSE; if (macroId != ltSECTIONSTAR) sectionNo ++; SetCurrentOutput(NULL); startedSections = TRUE; char *topicName = FindTopicName(GetNextChunk()); ReopenFile(&Sections, &SectionsName); AddTexRef(topicName, SectionsName, SectionNameString); SetCurrentSectionName(topicName, SectionsName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(1, topicName, SectionsName); SetCurrentOutput(Sections); HTMLHead(); TexOutput(""); OutputCurrentSection(); TexOutput("\n"); OutputBodyStart(); fprintf(Sections, "", topicName); AddBrowseButtons(CurrentChapterName, CurrentChapterFile, // Up lastTopic, lastFileName, // Last topic topicName, SectionsName); // This topic FILE *jumpFrom = ((DocumentStyle == LATEX_ARTICLE) ? Contents : Chapters); SetCurrentOutputs(jumpFrom, Sections); if (DocumentStyle == LATEX_ARTICLE) fprintf(jumpFrom, "\n
  • ", ConvertCase(SectionsName), topicName); else fprintf(jumpFrom, "\n", ConvertCase(SectionsName), topicName); fprintf(Sections, "\n

    "); OutputCurrentSection(); if (DocumentStyle == LATEX_ARTICLE) fprintf(jumpFrom, "\n"); else fprintf(jumpFrom, "
    \n"); fprintf(Sections, "

    \n"); SetCurrentOutput(Sections); // Add this section title to the list of keywords if (htmlIndex) { OutputCurrentSectionToString(wxTex2RTFBuffer); AddKeyWordForTopic(topicName, wxTex2RTFBuffer, currentFileName); } } break; } case ltSUBSECTION: case ltSUBSECTIONSTAR: case ltMEMBERSECTION: case ltFUNCTIONSECTION: { if (!start) { if (!Sections) { OnError("You cannot have a subsection before a section!"); } else { subsubsectionNo = 0; if (macroId != ltSUBSECTIONSTAR) subsectionNo ++; if ( combineSubSections && !subsectionStarted ) { // Read old .con file in at this point char buf[256]; strcpy(buf, CurrentSectionFile); wxStripExtension(buf); strcat(buf, ".con"); FILE *fd = fopen(buf, "r"); if ( fd ) { int ch = getc(fd); while (ch != EOF) { putc(ch, Sections); ch = getc(fd); } fclose(fd); } fprintf(Sections, "

    \n"); // Close old file, create a new file for the sub(sub)section contents entries ReopenSectionContentsFile(); } startedSections = TRUE; subsectionStarted = TRUE; char *topicName = FindTopicName(GetNextChunk()); if ( !combineSubSections ) { SetCurrentOutput(NULL); ReopenFile(&Subsections, &SubsectionsName); AddTexRef(topicName, SubsectionsName, SubsectionNameString); SetCurrentSubsectionName(topicName, SubsectionsName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SubsectionsName); SetCurrentOutput(Subsections); HTMLHead(); TexOutput(""); OutputCurrentSection(); TexOutput("\n"); OutputBodyStart(); fprintf(Subsections, "", topicName); AddBrowseButtons(CurrentSectionName, CurrentSectionFile, // Up lastTopic, lastFileName, // Last topic topicName, SubsectionsName); // This topic SetCurrentOutputs(Sections, Subsections); fprintf(Sections, "\n", ConvertCase(SubsectionsName), topicName); fprintf(Subsections, "\n

    "); OutputCurrentSection(); fprintf(Sections, "
    \n"); fprintf(Subsections, "

    \n"); SetCurrentOutput(Subsections); } else { AddTexRef(topicName, SectionsName, SubsectionNameString); SetCurrentSubsectionName(topicName, SectionsName); // if ( subsectionNo != 0 ) fprintf(Sections, "\n
    \n"); // We're putting everything into the section file fprintf(Sections, "", topicName); fprintf(Sections, "\n

    "); OutputCurrentSection(); fprintf(Sections, "

    \n"); SetCurrentOutput(SectionContentsFD); fprintf(SectionContentsFD, "", topicName); OutputCurrentSection(); TexOutput("
    \n"); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SectionsName); SetCurrentOutput(Sections); } // Add this section title to the list of keywords if (htmlIndex) { OutputCurrentSectionToString(wxTex2RTFBuffer); AddKeyWordForTopic(topicName, wxTex2RTFBuffer, currentFileName); } } } break; } case ltSUBSUBSECTION: case ltSUBSUBSECTIONSTAR: { if (!start) { if (!Subsections && !combineSubSections) { OnError("You cannot have a subsubsection before a subsection!"); } else { if (macroId != ltSUBSUBSECTIONSTAR) subsubsectionNo ++; startedSections = TRUE; char *topicName = FindTopicName(GetNextChunk()); if ( !combineSubSections ) { SetCurrentOutput(NULL); ReopenFile(&Subsubsections, &SubsubsectionsName); AddTexRef(topicName, SubsubsectionsName, SubsubsectionNameString); SetCurrentSubsubsectionName(topicName, SubsubsectionsName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(3, topicName, SubsubsectionsName); SetCurrentOutput(Subsubsections); HTMLHead(); TexOutput(""); OutputCurrentSection(); TexOutput("\n"); OutputBodyStart(); fprintf(Subsubsections, "", topicName); AddBrowseButtons(CurrentSubsectionName, CurrentSubsectionFile, // Up lastTopic, lastFileName, // Last topic topicName, SubsubsectionsName); // This topic SetCurrentOutputs(Subsections, Subsubsections); fprintf(Subsections, "\n", ConvertCase(SubsubsectionsName), topicName); fprintf(Subsubsections, "\n

    "); OutputCurrentSection(); fprintf(Subsections, "
    \n"); fprintf(Subsubsections, "

    \n"); } else { AddTexRef(topicName, SectionsName, SubsubsectionNameString); SetCurrentSubsectionName(topicName, SectionsName); fprintf(Sections, "\n
    \n"); // We're putting everything into the section file fprintf(Sections, "", topicName); fprintf(Sections, "\n

    "); OutputCurrentSection(); fprintf(Sections, "

    \n"); /* TODO: where do we put subsubsection contents entry - indented, with subsection entries? SetCurrentOutput(SectionContentsFD); fprintf(SectionContentsFD, "", topicName); OutputCurrentSection(); TexOutput("
    "); */ if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SectionsName); SetCurrentOutput(Sections); } // Add this section title to the list of keywords if (htmlIndex) { OutputCurrentSectionToString(wxTex2RTFBuffer); AddKeyWordForTopic(topicName, wxTex2RTFBuffer, currentFileName); } } } break; } case ltFUNC: case ltPFUNC: { if ( !combineSubSections ) SetCurrentOutput(Subsections); else SetCurrentOutput(Sections); if (start) { } else { } break; } case ltCLIPSFUNC: { if ( !combineSubSections ) SetCurrentOutput(Subsections); else SetCurrentOutput(Sections); if (start) { } else { } break; } case ltMEMBER: { if ( !combineSubSections ) SetCurrentOutput(Subsections); else SetCurrentOutput(Sections); if (start) { } else { } break; } case ltVOID: // if (start) // TexOutput("void"); break; case ltHARDY: if (start) TexOutput("HARDY"); break; case ltWXCLIPS: if (start) TexOutput("wxCLIPS"); break; case ltAMPERSAND: if (start) TexOutput("&"); break; case ltSPECIALAMPERSAND: { if (start) { if (inTabular) { // End cell, start cell TexOutput("
    "); // Start new row and cell, setting alignment for the first cell. if (currentColumn < noColumns) currentColumn ++; char buf[100]; if (TableData[currentColumn].justification == 'c') sprintf(buf, "\n"); else if (TableData[currentColumn].justification == 'r') sprintf(buf, "\n"); else if (TableData[currentColumn].absWidth) { // Convert from points * 20 into pixels. int points = TableData[currentColumn].width / 20; // Say the display is 100 DPI (dots/pixels per inch). // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots. int pixels = (int)(points * 100.0 / 72.0); sprintf(buf, "", pixels); } else sprintf(buf, "\n"); TexOutput(buf); OutputFont(); } else TexOutput("&"); } break; } case ltBACKSLASHCHAR: { if (start) { if (inTabular) { // End row. In fact, tables without use of \row or \ruledrow isn't supported for // HTML: the syntax is too different (e.g. how do we know where to put the first // if we've ended the last row?). So normally you wouldn't use \\ to end a row. TexOutput("\n"); } else TexOutput("
    \n"); } break; } case ltROW: case ltRULEDROW: { if (start) { currentColumn = 0; // Start new row and cell, setting alignment for the first cell. char buf[100]; if (TableData[currentColumn].justification == 'c') sprintf(buf, "\n"); else if (TableData[currentColumn].justification == 'r') sprintf(buf, "\n"); else if (TableData[currentColumn].absWidth) { // Convert from points * 20 into pixels. int points = TableData[currentColumn].width / 20; // Say the display is 100 DPI (dots/pixels per inch). // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots. int pixels = (int)(points * 100.0 / 72.0); sprintf(buf, "\n", pixels); } else sprintf(buf, "\n"); TexOutput(buf); OutputFont(); } else { // End cell and row // Start new row and cell TexOutput("
    \n\n"); } break; } // HTML-only: break until the end of the picture (both margins are clear). case ltBRCLEAR: { if (start) TexOutput("
    "); break; } case ltRTFSP: // Explicit space, RTF only break; case ltSPECIALTILDE: { if (start) { if (inVerbatim) TexOutput("~"); else TexOutput(" "); } break; } case ltINDENTED : { if ( start ) TexOutput("\n"); break; } case ltITEMIZE: case ltENUMERATE: case ltDESCRIPTION: // case ltTWOCOLLIST: { if (start) { indentLevel ++; int listType; if (macroId == ltENUMERATE) listType = LATEX_ENUMERATE; else if (macroId == ltITEMIZE) listType = LATEX_ITEMIZE; else listType = LATEX_DESCRIPTION; itemizeStack.Insert(new ItemizeStruc(listType)); switch (listType) { case LATEX_ITEMIZE: TexOutput("\n"); break; case LATEX_ENUMERATE: TexOutput("\n"); break; case LATEX_DESCRIPTION: default: TexOutput("\n"); break; } delete struc; delete itemizeStack.First(); } } break; } case ltTWOCOLLIST : { if ( start ) TexOutput("\n\n"); else { TexOutput("\n
    \n"); // DHS TwoColWidthA = -1; TwoColWidthB = -1; } break; } case ltPAR: { if (start) TexOutput("

    \n"); break; } /* For footnotes we need to output the text at the bottom of the page and * insert a reference to it. Is it worth the trouble... case ltFOOTNOTE: case ltFOOTNOTEPOPUP: { if (start) { TexOutput("); } else TexOutput(""); break; } */ case ltVERB: { if (start) TexOutput(""); else TexOutput(""); break; } case ltVERBATIM: { if (start) { char buf[100]; sprintf(buf, "

    \n");
          TexOutput(buf);
        }
        else TexOutput("
    \n"); break; } case ltCENTERLINE: case ltCENTER: { if (start) { TexOutput("
    "); } else TexOutput("
    "); break; } case ltFLUSHLEFT: { /* if (start) { TexOutput("{\\ql "); } else TexOutput("}\\par\\pard\n"); */ break; } case ltFLUSHRIGHT: { /* if (start) { TexOutput("{\\qr "); } else TexOutput("}\\par\\pard\n"); */ break; } case ltSMALL: { if (start) { // Netscape extension TexOutput(""); } else TexOutput(""); break; } case ltTINY: { if (start) { // Netscape extension TexOutput(""); } else TexOutput(""); break; } case ltNORMALSIZE: { if (start) { // Netscape extension TexOutput(""); } else TexOutput(""); break; } case ltlarge: { if (start) { // Netscape extension TexOutput(""); } else TexOutput(""); break; } case ltLarge: { if (start) { // Netscape extension TexOutput(""); } else TexOutput(""); break; } case ltLARGE: { if (start) { // Netscape extension TexOutput(""); } else TexOutput(""); break; } case ltBFSERIES: case ltTEXTBF: case ltBF: { if (start) { TexOutput(""); } else TexOutput(""); break; } case ltITSHAPE: case ltTEXTIT: case ltIT: { if (start) { TexOutput(""); } else TexOutput(""); break; } case ltEMPH: case ltEM: { if (start) { TexOutput(""); } else TexOutput(""); break; } case ltUNDERLINE: { if (start) { TexOutput(""); break; } case ltTTFAMILY: case ltTEXTTT: case ltTT: { if (start) { TexOutput(""); } else TexOutput(""); break; } case ltCOPYRIGHT: { if (start) TexOutput("©", TRUE); break; } case ltREGISTERED: { if (start) TexOutput("®", TRUE); break; } // Arrows case ltLEFTARROW: { if (start) TexOutput("<--"); break; } case ltLEFTARROW2: { if (start) TexOutput("<=="); break; } case ltRIGHTARROW: { if (start) TexOutput("-->"); break; } case ltRIGHTARROW2: { if (start) TexOutput("==>"); break; } case ltLEFTRIGHTARROW: { if (start) TexOutput("<-->"); break; } case ltLEFTRIGHTARROW2: { if (start) TexOutput("<==>"); break; } /* case ltSC: { break; } */ case ltITEM: { if (!start) { wxNode *node = itemizeStack.First(); if (node) { ItemizeStruc *struc = (ItemizeStruc *)node->Data(); struc->currentItem += 1; if (struc->listType == LATEX_DESCRIPTION) { if (descriptionItemArg) { TexOutput("
    "); TraverseChildrenFromChunk(descriptionItemArg); TexOutput("\n"); descriptionItemArg = NULL; } TexOutput("
    "); } else TexOutput("
  • "); } } break; } case ltMAKETITLE: { if (start && DocumentTitle && DocumentAuthor) { // Add a special label for the contents page. // TexOutput("
    \n"); TexOutput(""); TexOutput("

    \n"); TraverseChildrenFromChunk(DocumentTitle); TexOutput("

    "); TexOutput("

    "); TexOutput("\n"); TexOutput("

    \n\n"); TexOutput("

    "); TraverseChildrenFromChunk(DocumentAuthor); TexOutput("

    \n\n"); if (DocumentDate) { TexOutput("

    "); TraverseChildrenFromChunk(DocumentDate); TexOutput("

    \n\n"); } // TexOutput("\n

    \n"); TexOutput("\n


    \n"); /* // Now do optional frame contents page if (htmlFrameContents && FrameContents) { SetCurrentOutput(FrameContents); // Add a special label for the contents page. TexOutput("

    \n"); TexOutput("

    \n"); TraverseChildrenFromChunk(DocumentTitle); TexOutput("

    "); TexOutput("

    "); TexOutput("\n"); TexOutput("

    \n\n"); TexOutput("

    "); TraverseChildrenFromChunk(DocumentAuthor); TexOutput("

    \n\n"); if (DocumentDate) { TexOutput("

    "); TraverseChildrenFromChunk(DocumentDate); TexOutput("

    \n\n"); } TexOutput("\n

    \n"); TexOutput("


    \n"); SetCurrentOutput(Titlepage); } */ } break; } case ltHELPREF: case ltHELPREFN: case ltPOPREF: case ltURLREF: { if (start) { helpRefFilename = NULL; helpRefText = NULL; } break; } case ltBIBLIOGRAPHY: { if (start) { DefaultOnMacro(macroId, no_args, start); } else { DefaultOnMacro(macroId, no_args, start); TexOutput("\n"); } break; } case ltHRULE: { if (start) { TexOutput("


    \n"); } break; } case ltRULE: { if (start) { TexOutput("
    \n"); } break; } case ltTABLEOFCONTENTS: { if (start) { FILE *fd = fopen(ContentsName, "r"); if (fd) { int ch = getc(fd); while (ch != EOF) { putc(ch, Titlepage); ch = getc(fd); } fclose(fd); } else { TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n"); OnInform("Run Tex2RTF again to include contents page."); } } break; } case ltLANGLEBRA: { if (start) TexOutput("<"); break; } case ltRANGLEBRA: { if (start) TexOutput(">"); break; } case ltQUOTE: case ltQUOTATION: { if (start) TexOutput("
    "); else TexOutput("
    "); break; } case ltCAPTION: case ltCAPTIONSTAR: { if (start) { if (inTabular) TexOutput("\n"); char figBuf[40]; if ( inFigure ) { figureNo ++; if (DocumentStyle != LATEX_ARTICLE) sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo); else sprintf(figBuf, "%s %d: ", FigureNameString, figureNo); } else { tableNo ++; if (DocumentStyle != LATEX_ARTICLE) sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, tableNo); else sprintf(figBuf, "%s %d: ", TableNameString, tableNo); } TexOutput(figBuf); } else { if (inTabular) TexOutput("\n\n"); char *topicName = FindTopicName(GetNextChunk()); int n = inFigure ? figureNo : tableNo; AddTexRef(topicName, NULL, NULL, ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n), ((DocumentStyle != LATEX_ARTICLE) ? n : 0)); } break; } case ltSS: { if (start) TexOutput("ß"); break; } case ltFIGURE: { if (start) inFigure = TRUE; else inFigure = FALSE; break; } case ltTABLE: { if (start) inTable = TRUE; else inTable = FALSE; break; } default: DefaultOnMacro(macroId, no_args, start); break; } } // Called on start/end of argument examination bool HTMLOnArgument(int macroId, int arg_no, bool start) { switch (macroId) { case ltCHAPTER: case ltCHAPTERSTAR: case ltCHAPTERHEADING: case ltSECTION: case ltSECTIONSTAR: case ltSECTIONHEADING: case ltSUBSECTION: case ltSUBSECTIONSTAR: case ltSUBSUBSECTION: case ltSUBSUBSECTIONSTAR: case ltGLOSS: case ltMEMBERSECTION: case ltFUNCTIONSECTION: { if (!start && (arg_no == 1)) currentSection = GetArgChunk(); return FALSE; break; } case ltFUNC: { if (start && (arg_no == 1)) TexOutput(""); if (!start && (arg_no == 1)) TexOutput(" "); if (start && (arg_no == 2)) { if (!suppressNameDecoration) TexOutput(""); currentMember = GetArgChunk(); } if (!start && (arg_no == 2)) { if (!suppressNameDecoration) TexOutput(""); } if (start && (arg_no == 3)) TexOutput("("); if (!start && (arg_no == 3)) TexOutput(")"); break; } case ltCLIPSFUNC: { if (start && (arg_no == 1)) TexOutput(""); if (!start && (arg_no == 1)) TexOutput(" "); if (start && (arg_no == 2)) { if (!suppressNameDecoration) TexOutput("( "); currentMember = GetArgChunk(); } if (!start && (arg_no == 2)) { } if (!start && (arg_no == 3)) TexOutput(")"); break; } case ltPFUNC: { if (!start && (arg_no == 1)) TexOutput(" "); if (start && (arg_no == 2)) TexOutput("(*"); if (!start && (arg_no == 2)) TexOutput(")"); if (start && (arg_no == 2)) currentMember = GetArgChunk(); if (start && (arg_no == 3)) TexOutput("("); if (!start && (arg_no == 3)) TexOutput(")"); break; } case ltPARAM: { if (start && (arg_no == 1)) TexOutput(""); if (!start && (arg_no == 1)) TexOutput(""); if (start && (arg_no == 2)) { TexOutput(""); } if (!start && (arg_no == 2)) { TexOutput(""); } break; } case ltCPARAM: { if (start && (arg_no == 1)) TexOutput(""); if (!start && (arg_no == 1)) TexOutput(" "); // This is the difference from param - one space! if (start && (arg_no == 2)) { TexOutput(""); } if (!start && (arg_no == 2)) { TexOutput(""); } break; } case ltMEMBER: { if (!start && (arg_no == 1)) TexOutput(" "); if (start && (arg_no == 2)) currentMember = GetArgChunk(); break; } case ltREF: { if (start) { char *sec = NULL; char *refName = GetArgData(); if (refName) { TexRef *texRef = FindReference(refName); if (texRef) { sec = texRef->sectionNumber; } } if (sec) { TexOutput(sec); } return FALSE; } break; } case ltURLREF: { if (IsArgOptional()) return FALSE; else if ((GetNoArgs() - arg_no) == 1) { if (start) helpRefText = GetArgChunk(); return FALSE; } else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional { if (start) { TexChunk *ref = GetArgChunk(); TexOutput(""); if (helpRefText) TraverseChildrenFromChunk(helpRefText); TexOutput(""); } return FALSE; } break; } case ltHELPREF: case ltHELPREFN: case ltPOPREF: { if (IsArgOptional()) { if (start) helpRefFilename = GetArgChunk(); return FALSE; } if ((GetNoArgs() - arg_no) == 1) { if (start) helpRefText = GetArgChunk(); return FALSE; } else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional { if (start) { char *refName = GetArgData(); char *refFilename = NULL; if (refName) { TexRef *texRef = FindReference(refName); if (texRef) { if (texRef->refFile && strcmp(texRef->refFile, "??") != 0) refFilename = texRef->refFile; TexOutput(""); if (helpRefText) TraverseChildrenFromChunk(helpRefText); TexOutput(""); } else { if (helpRefText) TraverseChildrenFromChunk(helpRefText); if (!ignoreBadRefs) TexOutput(" (REF NOT FOUND)"); wxString errBuf; errBuf.Printf("Warning: unresolved reference '%s'", refName); OnInform((char *)errBuf.c_str()); } } else TexOutput("??"); } return FALSE; } break; } case ltIMAGE: case ltIMAGEL: case ltIMAGER: case ltPSBOXTO: { if (arg_no == 2) { if (start) { char *alignment = ""; if (macroId == ltIMAGEL) alignment = " align=left"; else if (macroId == ltIMAGER) alignment = " align=right"; // Try to find an XBM or GIF image first. char *filename = copystring(GetArgData()); char buf[500]; strcpy(buf, filename); StripExtension(buf); strcat(buf, ".xbm"); wxString f = TexPathList.FindValidPath(buf); if (f == "") // Try for a GIF instead { strcpy(buf, filename); StripExtension(buf); strcat(buf, ".gif"); f = TexPathList.FindValidPath(buf); } if (f == "") // Try for a JPEG instead { strcpy(buf, filename); StripExtension(buf); strcat(buf, ".jpg"); f = TexPathList.FindValidPath(buf); } if (f == "") // Try for a PNG instead { strcpy(buf, filename); StripExtension(buf); strcat(buf, ".png"); f = TexPathList.FindValidPath(buf); } if (f != "") { char *inlineFilename = copystring(f); #if 0 char *originalFilename = TexPathList.FindValidPath(filename); // If we have found the existing filename, make the inline // image point to the original file (could be PS, for example) if (originalFilename && (strcmp(inlineFilename, originalFilename) != 0)) { TexOutput(""); TexOutput(""); } else #endif { TexOutput(""); delete[] inlineFilename; } } else { // Last resort - a link to a PS file. TexOutput("Picture\n"); sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename); OnInform(buf); } } } return FALSE; break; } // First arg is PSBOX spec (ignored), second is image file, third is map name. case ltIMAGEMAP: { static char *imageFile = NULL; if (start && (arg_no == 2)) { // Try to find an XBM or GIF image first. char *filename = copystring(GetArgData()); char buf[500]; strcpy(buf, filename); StripExtension(buf); strcat(buf, ".xbm"); wxString f = TexPathList.FindValidPath(buf); if (f == "") // Try for a GIF instead { strcpy(buf, filename); StripExtension(buf); strcat(buf, ".gif"); f = TexPathList.FindValidPath(buf); } if (f == "") { char buf[300]; sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename); OnInform(buf); } delete[] filename; if (imageFile) delete[] imageFile; imageFile = NULL; if (!f.IsEmpty()) { imageFile = copystring(f); } } else if (start && (arg_no == 3)) { if (imageFile) { // First, try to find a .shg (segmented hypergraphics file) // that we can convert to a map file char buf[256]; strcpy(buf, imageFile); StripExtension(buf); strcat(buf, ".shg"); wxString f = TexPathList.FindValidPath(buf); if (f != "") { // The default HTML file to go to is THIS file (so a no-op) SHGToMap((char*) (const char*) f, currentFileName); } char *mapName = GetArgData(); TexOutput(""); TexOutput("

    "); delete[] imageFile; imageFile = NULL; } } return FALSE; break; } case ltINDENTED : { if ( arg_no == 1 ) return FALSE; else { return TRUE; } } case ltITEM: { if (start) { descriptionItemArg = GetArgChunk(); return FALSE; } return TRUE; } case ltTWOCOLITEM: case ltTWOCOLITEMRULED: { /* if (start && (arg_no == 1)) TexOutput("\n

    "); if (start && (arg_no == 2)) TexOutput("
    "); */ if (arg_no == 1) { if ( start ) { // DHS if (TwoColWidthA > -1) { char buf[100]; sprintf(buf,"\n\n",TwoColWidthA); TexOutput(buf); } else TexOutput("\n\n"); OutputFont(); } else TexOutput("\n\n"); } if (arg_no == 2) { // DHS if ( start ) { if (TwoColWidthB > -1) { char buf[100]; sprintf(buf,"\n\n",TwoColWidthB); TexOutput(buf); } else TexOutput("\n\n"); OutputFont(); } else TexOutput("\n\n"); } return TRUE; break; } case ltNUMBEREDBIBITEM: { if (arg_no == 1 && start) { TexOutput("\n
    "); } if (arg_no == 2 && !start) TexOutput("

    \n"); break; } case ltBIBITEM: { char buf[100]; if (arg_no == 1 && start) { char *citeKey = GetArgData(); TexRef *ref = (TexRef *)TexReferences.Get(citeKey); if (ref) { if (ref->sectionNumber) delete[] ref->sectionNumber; sprintf(buf, "[%d]", citeCount); ref->sectionNumber = copystring(buf); } sprintf(buf, "\n

    [%d] ", citeCount); TexOutput(buf); citeCount ++; return FALSE; } if (arg_no == 2 && !start) TexOutput("

    \n"); return TRUE; break; } case ltMARGINPAR: case ltMARGINPARODD: case ltMARGINPAREVEN: case ltNORMALBOX: case ltNORMALBOXD: { if (start) { TexOutput("


    \n"); return TRUE; } else TexOutput("

    \n"); break; } // DHS case ltTWOCOLWIDTHA: { if (start) { char *val = GetArgData(); float points = ParseUnitArgument(val); TwoColWidthA = (int)((points * 100.0) / 72.0); } return FALSE; break; } // DHS case ltTWOCOLWIDTHB: { if (start) { char *val = GetArgData(); float points = ParseUnitArgument(val); TwoColWidthB = (int)((points * 100.0) / 72.0); } return FALSE; break; } /* * Accents * */ case ltACCENT_GRAVE: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case 'a': TexOutput("à"); break; case 'e': TexOutput("è"); break; case 'i': TexOutput("ì"); break; case 'o': TexOutput("ò"); break; case 'u': TexOutput("ù"); break; case 'A': TexOutput("À"); break; case 'E': TexOutput("È"); break; case 'I': TexOutput("Ì"); break; case 'O': TexOutput("Ò"); break; case 'U': TexOutput("Ì"); break; default: break; } } } return FALSE; break; } case ltACCENT_ACUTE: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case 'a': TexOutput("á"); break; case 'e': TexOutput("é"); break; case 'i': TexOutput("í"); break; case 'o': TexOutput("ó"); break; case 'u': TexOutput("ú"); break; case 'y': TexOutput("ý"); break; case 'A': TexOutput("Á"); break; case 'E': TexOutput("É"); break; case 'I': TexOutput("Í"); break; case 'O': TexOutput("Ó"); break; case 'U': TexOutput("Ú"); break; case 'Y': TexOutput("Ý"); break; default: break; } } } return FALSE; break; } case ltACCENT_CARET: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case 'a': TexOutput("â"); break; case 'e': TexOutput("ê"); break; case 'i': TexOutput("î"); break; case 'o': TexOutput("ô"); break; case 'u': TexOutput("û"); break; case 'A': TexOutput("Â"); break; case 'E': TexOutput("Ê"); break; case 'I': TexOutput("Î"); break; case 'O': TexOutput("Ô"); break; case 'U': TexOutput("Î"); break; default: break; } } } return FALSE; break; } case ltACCENT_TILDE: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case ' ': TexOutput("~"); break; case 'a': TexOutput("ã"); break; case 'n': TexOutput("ñ"); break; case 'o': TexOutput("õ"); break; case 'A': TexOutput("Ã"); break; case 'N': TexOutput("Ñ"); break; case 'O': TexOutput("Õ"); break; default: break; } } } return FALSE; break; } case ltACCENT_UMLAUT: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case 'a': TexOutput("ä"); break; case 'e': TexOutput("ë"); break; case 'i': TexOutput("ï"); break; case 'o': TexOutput("ö"); break; case 'u': TexOutput("ü"); break; case 'y': TexOutput("ÿ"); break; case 'A': TexOutput("Ä"); break; case 'E': TexOutput("Ë"); break; case 'I': TexOutput("Ï"); break; case 'O': TexOutput("Ö"); break; case 'U': TexOutput("Ü"); break; case 'Y': TexOutput("Ÿ"); break; default: break; } } } return FALSE; break; } case ltACCENT_DOT: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case 'a': TexOutput("å"); break; case 'A': TexOutput("Å"); break; default: break; } } } return FALSE; break; } case ltBACKGROUND: { if (start) { char *val = GetArgData(); if (val) { bool isPicture = FALSE; char *s = ParseColourString(val, &isPicture); if (isPicture) { if (backgroundImageString) delete[] backgroundImageString; backgroundImageString = copystring(val); } else { if (backgroundColourString) delete[] backgroundColourString; backgroundColourString = copystring(val); } } } return FALSE; break; } case ltBACKGROUNDIMAGE: { if (start) { char *val = GetArgData(); if (val) { if (backgroundImageString) delete[] backgroundImageString; backgroundImageString = copystring(val); } } return FALSE; break; } case ltBACKGROUNDCOLOUR: { if (start) { char *val = GetArgData(); if (val) { if (backgroundColourString) delete[] backgroundColourString; backgroundColourString = copystring(val); } } return FALSE; break; } case ltTEXTCOLOUR: { if (start) { char *val = GetArgData(); if (val) { if (textColourString) delete[] textColourString; textColourString = copystring(val); } } return FALSE; break; } case ltLINKCOLOUR: { if (start) { char *val = GetArgData(); if (val) { if (linkColourString) delete[] linkColourString; linkColourString = copystring(val); } } return FALSE; break; } case ltFOLLOWEDLINKCOLOUR: { if (start) { char *val = GetArgData(); if (val) { if (followedLinkColourString) delete[] followedLinkColourString; followedLinkColourString = copystring(val); } } return FALSE; break; } case ltACCENT_CADILLA: { if (start) { char *val = GetArgData(); if (val) { switch (val[0]) { case 'c': TexOutput("ç"); break; case 'C': TexOutput("Ç"); break; default: break; } } } return FALSE; break; } /* case ltFOOTNOTE: case ltFOOTNOTEPOPUP: { if (arg_no == 1) return TRUE; else return FALSE; break; } */ case ltTABULAR: case ltSUPERTABULAR: { if (arg_no == 1) { if (start) { currentRowNumber = 0; inTabular = TRUE; startRows = TRUE; tableVerticalLineLeft = FALSE; tableVerticalLineRight = FALSE; int currentWidth = 0; char *alignString = copystring(GetArgData()); ParseTableArgument(alignString); TexOutput("\n"); // Write the first row formatting for compatibility // with standard Latex if (compatibilityMode) { TexOutput("\n
    "); OutputFont(); /* for (int i = 0; i < noColumns; i++) { currentWidth += TableData[i].width; sprintf(buf, "\\cellx%d", currentWidth); TexOutput(buf); } TexOutput("\\pard\\intbl\n"); */ } delete[] alignString; return FALSE; } } else if (arg_no == 2 && !start) { TexOutput("
    \n"); inTabular = FALSE; } break; } case ltTHEBIBLIOGRAPHY: { if (start && (arg_no == 1)) { ReopenFile(&Chapters, &ChaptersName); AddTexRef("bibliography", ChaptersName, "bibliography"); SetCurrentSubsectionName("bibliography", ChaptersName); citeCount = 1; SetCurrentOutput(Chapters); char titleBuf[150]; if (truncateFilenames) sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot)); else sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot)); HTMLHead(); TexOutput(""); TexOutput(ReferencesNameString); TexOutput("\n"); OutputBodyStart(); fprintf(Chapters, "\n

    %s", "bibliography", ReferencesNameString); AddBrowseButtons("contents", titleBuf, // Up lastTopic, lastFileName, // Last topic "bibliography", ChaptersName); // This topic SetCurrentOutputs(Contents, Chapters); fprintf(Contents, "\n
  • ", ConvertCase(ChaptersName), "bibliography"); fprintf(Contents, "%s\n", ReferencesNameString); fprintf(Chapters, "
  • \n\n"); SetCurrentOutput(Chapters); return FALSE; } if (!start && (arg_no == 2)) { } return TRUE; break; } case ltINDEX: { /* Build up list of keywords associated with topics */ if (start) { // char *entry = GetArgData(); char buf[300]; OutputChunkToString(GetArgChunk(), buf); if (CurrentTopic) { AddKeyWordForTopic(CurrentTopic, buf, currentFileName); } } return FALSE; break; } case ltFCOL: // case ltBCOL: { if (start) { switch (arg_no) { case 1: { char *name = GetArgData(); char buf2[10]; if (!FindColourHTMLString(name, buf2)) { strcpy(buf2, "#000000"); char buf[100]; sprintf(buf, "Could not find colour name %s", name); OnError(buf); } TexOutput(""); break; } case 2: { return TRUE; break; } default: break; } } else { if (arg_no == 2) TexOutput(""); } return FALSE; break; } case ltINSERTATLEVEL: { // This macro allows you to insert text at a different level // from the current level, e.g. into the Sections from within a subsubsection. if (useWord) return FALSE; static int currentLevelNo = 1; static FILE* oldLevelFile = Chapters; if (start) { switch (arg_no) { case 1: { oldLevelFile = CurrentOutput1; char *str = GetArgData(); currentLevelNo = atoi(str); FILE* outputFile; // TODO: cope with article style (no chapters) switch (currentLevelNo) { case 1: { outputFile = Chapters; break; } case 2: { outputFile = Sections; break; } case 3: { outputFile = Subsections; break; } case 4: { outputFile = Subsubsections; break; } default: { outputFile = NULL; break; } } if (outputFile) CurrentOutput1 = outputFile; return FALSE; break; } case 2: { return TRUE; break; } default: break; } return TRUE; } else { if (arg_no == 2) { CurrentOutput1 = oldLevelFile; } return TRUE; } } default: return DefaultOnArgument(macroId, arg_no, start); break; } return TRUE; } bool HTMLGo(void) { fileId = 0; inVerbatim = FALSE; indentLevel = 0; inTabular = FALSE; startRows = FALSE; tableVerticalLineLeft = FALSE; tableVerticalLineRight = FALSE; noColumns = 0; if (InputFile && OutputFile) { // Do some HTML-specific transformations on all the strings, // recursively Text2HTML(GetTopLevelChunk()); char buf[300]; if (truncateFilenames) sprintf(buf, "%s.htm", FileRoot); else sprintf(buf, "%s_contents.html", FileRoot); if (TitlepageName) delete[] TitlepageName; TitlepageName = copystring(buf); Titlepage = fopen(buf, "w"); if (truncateFilenames) sprintf(buf, "%s_fc.htm", FileRoot); else sprintf(buf, "%s_fcontents.html", FileRoot); contentsFrameName = copystring(buf); Contents = fopen(TmpContentsName, "w"); if (htmlFrameContents) { // FrameContents = fopen(TmpFrameContentsName, "w"); FrameContents = fopen(contentsFrameName, "w"); fprintf(FrameContents, "\n
      \n"); } if (!Titlepage || !Contents) { OnError("Cannot open output file!"); return FALSE; } AddTexRef("contents", FileNameFromPath(TitlepageName), ContentsNameString); fprintf(Contents, "

      %s

      \n", ContentsNameString); fprintf(Contents, "

        \n"); SetCurrentOutput(Titlepage); if (htmlWorkshopFiles) HTMLWorkshopStartContents(); OnInform("Converting..."); TraverseDocument(); fprintf(Contents, "
      \n\n"); // SetCurrentOutput(Titlepage); fclose(Titlepage); if (Contents) { // fprintf(Titlepage, "\n\n"); fclose(Contents); Contents = NULL; } if (FrameContents) { fprintf(FrameContents, "\n
    \n"); fprintf(FrameContents, "\n"); fclose(FrameContents); FrameContents = NULL; } if (Chapters) { fprintf(Chapters, "\n\n"); fclose(Chapters); Chapters = NULL; } if (Sections) { fprintf(Sections, "\n\n"); fclose(Sections); Sections = NULL; } if (Subsections && !combineSubSections) { fprintf(Subsections, "\n\n"); fclose(Subsections); Subsections = NULL; } if (Subsubsections && !combineSubSections) { fprintf(Subsubsections, "\n\n"); fclose(Subsubsections); Subsubsections = NULL; } if ( SectionContentsFD ) { fclose(SectionContentsFD); SectionContentsFD = NULL; } // Create a temporary file for the title page header, add some info, // and concat the titlepage just generated. // This is necessary in order to put the title of the document // at the TOP of the file within , even though we only find out // what it is later on. FILE *tmpTitle = fopen("title.tmp", "w"); if (tmpTitle) { if (DocumentTitle) { SetCurrentOutput(tmpTitle); HTMLHead(); TexOutput("\n"); TraverseChildrenFromChunk(DocumentTitle); TexOutput("\n"); } else { SetCurrentOutput(tmpTitle); HTMLHeadTo(tmpTitle); if (contentsString) fprintf(tmpTitle, "%s\n\n", contentsString); else fprintf(tmpTitle, "%s\n\n", FileNameFromPath(FileRoot)); } // Output frame information if (htmlFrameContents) { char firstFileName[300]; if (truncateFilenames) sprintf(firstFileName, "%s1.htm", FileRoot); else sprintf(firstFileName, "%s1.html", FileRoot); fprintf(tmpTitle, "\n"); fprintf(tmpTitle, "\n", ConvertCase(FileNameFromPath(contentsFrameName))); fprintf(tmpTitle, "\n", ConvertCase(FileNameFromPath(firstFileName))); fprintf(tmpTitle, "\n"); fprintf(tmpTitle, "\n"); } // Output <BODY...> to temporary title page OutputBodyStart(); // Concat titlepage FILE *fd = fopen(TitlepageName, "r"); if (fd) { int ch = getc(fd); while (ch != EOF) { putc(ch, tmpTitle); ch = getc(fd); } fclose(fd); } fprintf(tmpTitle, "\n</FONT></BODY>\n"); if (htmlFrameContents) { fprintf(tmpTitle, "\n\n"); } fprintf(tmpTitle, "\n\n"); fclose(tmpTitle); if (FileExists(TitlepageName)) wxRemoveFile(TitlepageName); if (!wxRenameFile("title.tmp", TitlepageName)) { wxCopyFile("title.tmp", TitlepageName); wxRemoveFile("title.tmp"); } } if (lastFileName) delete[] lastFileName; lastFileName = NULL; if (lastTopic) delete[] lastTopic; lastTopic = NULL; if (FileExists(ContentsName)) wxRemoveFile(ContentsName); if (!wxRenameFile(TmpContentsName, ContentsName)) { wxCopyFile(TmpContentsName, ContentsName); wxRemoveFile(TmpContentsName); } // Generate .htx file if requested if (htmlIndex) { char htmlIndexName[300]; sprintf(htmlIndexName, "%s.htx", FileRoot); GenerateHTMLIndexFile(htmlIndexName); } // Generate HTML Help Workshop files if requested if (htmlWorkshopFiles) { HTMLWorkshopEndContents(); GenerateHTMLWorkshopFiles(FileRoot); } return TRUE; } return FALSE; } // Output .htx index file void GenerateHTMLIndexFile(char *fname) { FILE *fd = fopen(fname, "w"); if (!fd) return; TopicTable.BeginFind(); wxNode *node = NULL; while ((node = TopicTable.Next())) { TexTopic *texTopic = (TexTopic *)node->Data(); const char *topicName = node->GetKeyString(); if (texTopic->filename && texTopic->keywords) { wxNode *node1 = texTopic->keywords->First(); while (node1) { char *s = (char *)node1->Data(); fprintf(fd, "%s|%s|%s\n", topicName, texTopic->filename, s); node1 = node1->Next(); } } } fclose(fd); } // output .hpp, .hhc and .hhk files: void GenerateHTMLWorkshopFiles(char *fname) { FILE *f; char buf[300]; /* Generate project file : */ sprintf(buf, "%s.hhp", fname); f = fopen(buf, "wt"); fprintf(f, "[OPTIONS]\n" "Compatibility=1.1\n" "Full-text search=Yes\n" "Contents file=%s.hhc\n" "Compiled file=%s.chm\n" "Default Window=%sHelp\n" "Default topic=%s\n" "Index file=%s.hhk\n" "Title=", FileNameFromPath(fname), FileNameFromPath(fname), FileNameFromPath(fname), FileNameFromPath(TitlepageName), FileNameFromPath(fname) ); if (DocumentTitle) { SetCurrentOutput(f); TraverseChildrenFromChunk(DocumentTitle); } else fprintf(f, "(unknown)"); fprintf(f, "\n\n[WINDOWS]\n" "%sHelp=,\"%s.hhc\",\"%s.hhk\",\"%s\",,,,,,0x2420,,0x380e,,,,,0,,,", FileNameFromPath(fname), FileNameFromPath(fname), FileNameFromPath(fname), FileNameFromPath(TitlepageName)); fprintf(f, "\n\n[FILES]\n"); fprintf(f, "%s\n", FileNameFromPath(TitlepageName)); for (int i = 1; i <= fileId; i++) { if (truncateFilenames) sprintf(buf, "%s%d.htm", FileNameFromPath(FileRoot), i); else sprintf(buf, "%s%d.html", FileNameFromPath(FileRoot), i); fprintf(f, "%s\n", buf); } fclose(f); /* Generate index file : */ sprintf(buf, "%s.hhk", fname); f = fopen(buf, "wt"); fprintf(f, "\n" "\n"); HTMLHeadTo(f); fprintf(f, "\n" "\n" "\n" "\n" "\n" " \n" "\n" "
      \n"); TopicTable.BeginFind(); wxNode *node = NULL; while ((node = TopicTable.Next())) { TexTopic *texTopic = (TexTopic *)node->Data(); const char *topicName = node->GetKeyString(); if (texTopic->filename && texTopic->keywords) { wxNode *node1 = texTopic->keywords->First(); while (node1) { char *s = (char *)node1->Data(); fprintf(f, "
    • \n" " \n" " \n" " \n", texTopic->filename, topicName, s); node1 = node1->Next(); } } } fprintf(f, "
    \n"); fclose(f); } static FILE *HTMLWorkshopContents = NULL; static int HTMLWorkshopLastLevel = 0; void HTMLWorkshopAddToContents(int level, char *s, char *file) { int i; if (level > HTMLWorkshopLastLevel) for (i = HTMLWorkshopLastLevel; i < level; i++) fprintf(HTMLWorkshopContents, "
      "); if (level < HTMLWorkshopLastLevel) for (i = level; i < HTMLWorkshopLastLevel; i++) fprintf(HTMLWorkshopContents, "
    "); SetCurrentOutput(HTMLWorkshopContents); fprintf(HTMLWorkshopContents, "
  • \n" " \n" " \n" " \n"); HTMLWorkshopLastLevel = level; } void HTMLWorkshopStartContents() { char buf[300]; sprintf(buf, "%s.hhc", FileRoot); HTMLWorkshopContents = fopen(buf, "wt"); HTMLWorkshopLastLevel = 0; fprintf(HTMLWorkshopContents, "\n" "\n"); HTMLHeadTo(HTMLWorkshopContents); fprintf(HTMLWorkshopContents, "\n" "\n" "\n" "\n" "\n" " \n" "\n" "
      \n" "
    • \n" "\n" "\n\n", FileNameFromPath(TitlepageName) ); } void HTMLWorkshopEndContents() { for (int i = HTMLWorkshopLastLevel; i >= 0; i--) fprintf(HTMLWorkshopContents, "
    \n"); fclose(HTMLWorkshopContents); }