///////////////////////////////////////////////////////////////////////////// // Name: htmlutil.cpp // Purpose: Converts Latex to HTML // Author: Julian Smart // Modified by: Wlodzimierz ABX Skiba 2003/2004 Unicode support // Ron Lee // Created: 7.9.93 // RCS-ID: $Id: htmlutil.cpp 59105 2009-02-23 11:51:34Z VZ $ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #endif #include "wx/arrstr.h" #include "tex2any.h" #include "tex2rtf.h" #include "table.h" #include #define HTML_FILENAME_PATTERN _T("%s_%s.html") #if !WXWIN_COMPATIBILITY_2_4 static inline wxChar* copystring(const wxChar* s) { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); } #endif extern wxHashTable TexReferences; extern int passNumber; extern void DecToHex(int, wxChar *); void GenerateHTMLIndexFile(wxChar *fname); bool PrimaryAnchorOfTheFile( wxChar *file, wxChar *label ); void GenerateHTMLWorkshopFiles(wxChar *fname); void HTMLWorkshopAddToContents(int level, wxChar *s, wxChar *file); void HTMLWorkshopStartContents(); void HTMLWorkshopEndContents(); void OutputContentsFrame(void); #include "readshg.h" // Segmented hypergraphics parsing wxChar *ChaptersName = NULL; wxChar *SectionsName = NULL; wxChar *SubsectionsName = NULL; wxChar *SubsubsectionsName = NULL; wxChar *TitlepageName = NULL; wxChar *lastFileName = NULL; wxChar *lastTopic = NULL; wxChar *currentFileName = NULL; wxChar *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 wxChar *BigBuffer; // DHS Two-column table dimensions. static int TwoColWidthA = -1; static int TwoColWidthB = -1; class HyperReference: public wxObject { public: wxChar *refName; wxChar *refFile; HyperReference(wxChar *name, wxChar *file) { if (name) refName = copystring(name); if (file) refFile = copystring(file); } }; class TexNextPage: public wxObject { public: wxChar *label; wxChar *filename; TexNextPage(wxChar *theLabel, wxChar *theFile) { label = copystring(theLabel); filename = copystring(theFile); } virtual ~TexNextPage(void) { delete[] label; delete[] filename; } }; wxHashTable TexNextPages(wxKEY_STRING); static wxChar *CurrentChapterName = NULL; static wxChar *CurrentChapterFile = NULL; static wxChar *CurrentSectionName = NULL; static wxChar *CurrentSectionFile = NULL; static wxChar *CurrentSubsectionName = NULL; static wxChar *CurrentSubsectionFile = NULL; static wxChar *CurrentSubsubsectionName = NULL; static wxChar *CurrentSubsubsectionFile = NULL; static wxChar *CurrentTopic = NULL; static void SetCurrentTopic(wxChar *s) { if (CurrentTopic) delete[] CurrentTopic; CurrentTopic = copystring(s); } void SetCurrentChapterName(wxChar *s, wxChar *file) { if (CurrentChapterName) delete[] CurrentChapterName; CurrentChapterName = copystring(s); if (CurrentChapterFile) delete[] CurrentChapterFile; CurrentChapterFile = copystring(file); currentFileName = CurrentChapterFile; SetCurrentTopic(s); } void SetCurrentSectionName(wxChar *s, wxChar *file) { if (CurrentSectionName) delete[] CurrentSectionName; CurrentSectionName = copystring(s); if (CurrentSectionFile) delete[] CurrentSectionFile; CurrentSectionFile = copystring(file); currentFileName = CurrentSectionFile; SetCurrentTopic(s); } void SetCurrentSubsectionName(wxChar *s, wxChar *file) { if (CurrentSubsectionName) delete[] CurrentSubsectionName; CurrentSubsectionName = copystring(s); if (CurrentSubsectionFile) delete[] CurrentSubsectionFile; CurrentSubsectionFile = copystring(file); currentFileName = CurrentSubsectionFile; SetCurrentTopic(s); } void SetCurrentSubsubsectionName(wxChar *s, wxChar *file) { if (CurrentSubsubsectionName) delete[] CurrentSubsubsectionName; CurrentSubsubsectionName = copystring(s); if (CurrentSubsubsectionFile) delete[] CurrentSubsubsectionFile; CurrentSubsubsectionFile = copystring(file); currentFileName = CurrentSubsubsectionFile; SetCurrentTopic(s); } // mapping between fileId and filenames if truncateFilenames=false: static wxArrayString gs_filenames; /* * Close former filedescriptor and reopen using another filename. * */ void ReopenFile(FILE **fd, wxChar **fileName, const wxChar *label) { if (*fd) { wxFprintf(*fd, _T("\n\n")); fclose(*fd); } fileId ++; wxChar buf[400]; if (truncateFilenames) { wxSnprintf(buf, sizeof(buf), _T("%s%d.htm"), FileRoot, fileId); } else { if (fileId == 1) gs_filenames.Add(wxEmptyString); wxSnprintf(buf, sizeof(buf), HTML_FILENAME_PATTERN, FileRoot, label); gs_filenames.Add(buf); } if (*fileName) delete[] *fileName; *fileName = copystring(wxFileNameFromPath(buf)); *fd = wxFopen(buf, _T("w")); wxFprintf(*fd, _T("\n")); } /* * Reopen section contents file, i.e. the index appended to each section * in subsectionCombine mode */ static wxChar *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 ) { wxChar buf[256]; wxStrcpy(buf, CurrentSectionFile); wxStripExtension(buf); wxStrcat(buf, _T(".con")); SectionContentsFilename = copystring(buf); SectionContentsFD = wxFopen(SectionContentsFilename, _T("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; wxChar ch = 1; int len = wxStrlen(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; wxStrcat(BigBuffer, _T("

\n\n")); ptr += 5; i += 2; changed = true; } else if (!inVerbatim && ch == _T('`') && (len >= i+1 && chunk->value[i+1] == '`')) { BigBuffer[ptr] = '"'; ptr ++; i += 2; changed = true; } else if (!inVerbatim && ch == _T('`')) // Change ` to ' { BigBuffer[ptr] = 39; ptr ++; i += 1; changed = true; } else if (ch == _T('<')) // Change < to < { BigBuffer[ptr] = 0; wxStrcat(BigBuffer, _T("<")); ptr += 4; i += 1; changed = true; } else if (ch == _T('>')) // Change > to > { BigBuffer[ptr] = 0; wxStrcat(BigBuffer, _T(">")); 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.GetFirst(); while (node) { TexChunk *child_chunk = (TexChunk *)node->GetData(); Text2HTML(child_chunk); node = node->GetNext(); } if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL)) inVerbatim = false; break; } case CHUNK_TYPE_ARG: { wxNode *node = chunk->children.GetFirst(); while (node) { TexChunk *child_chunk = (TexChunk *)node->GetData(); Text2HTML(child_chunk); node = node->GetNext(); } break; } case CHUNK_TYPE_STRING: { if (chunk->value) ProcessText2HTML(chunk); break; } } } /* * Add appropriate browse buttons to this page. * */ void AddBrowseButtons(wxChar *upLabel, wxChar *upFilename, wxChar *previousLabel, wxChar *previousFilename, wxChar *thisLabel, wxChar *thisFilename) { wxChar contentsReferenceBuf[80]; wxChar upReferenceBuf[80]; wxChar backReferenceBuf[80]; wxChar forwardReferenceBuf[80]; if (htmlBrowseButtons == HTML_BUTTONS_NONE) return; wxChar *contentsReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) contentsReference = ContentsNameString; else { // contentsReference = "\"Contents\""; contentsReference = contentsReferenceBuf; wxSnprintf(contentsReference, sizeof(contentsReferenceBuf), _T("\"Contents\""), ConvertCase(_T("contents.gif"))); } wxChar *upReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) upReference = UpNameString; else { // upReference = "\"Up\""; upReference = upReferenceBuf; wxSnprintf(upReference, sizeof(upReferenceBuf), _T("\"Up\""), ConvertCase(_T("up.gif"))); } wxChar *backReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) backReference = _T("<<"); else { // backReference = "\"Previous\""; backReference = backReferenceBuf; wxSnprintf(backReference, sizeof(backReferenceBuf), _T("\"Previous\""), ConvertCase(_T("back.gif"))); } wxChar *forwardReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) forwardReference = _T(">>"); else { // forwardReference = "\"Next\""; forwardReference = forwardReferenceBuf; wxSnprintf(forwardReference, sizeof(forwardReferenceBuf), _T("\"Next\""), ConvertCase(_T("forward.gif"))); } TexOutput(_T("

")); wxChar buf[200]; /* * Contents button * */ if (truncateFilenames) { wxChar buf1[80]; wxStrcpy(buf1, ConvertCase(wxFileNameFromPath(FileRoot))); wxSnprintf(buf, sizeof(buf), _T("\n%s "), buf1, ConvertCase(_T("htm")), contentsReference); } else { wxChar buf1[80]; wxStrcpy(buf1, ConvertCase(wxFileNameFromPath(FileRoot))); wxSnprintf(buf, sizeof(buf), _T("\n%s "), buf1, ConvertCase(_T("_contents.html")), contentsReference); } // TexOutput(_T("")); TexOutput(buf); // TexOutput(_T("")); /* * Up button * */ if (upLabel && upFilename) { if ( (wxStrlen(upLabel) > 0) && !PrimaryAnchorOfTheFile(upFilename, upLabel) ) wxSnprintf(buf, sizeof(buf), _T("%s "), ConvertCase(upFilename), upLabel, upReference); else wxSnprintf(buf, sizeof(buf), _T("%s "), ConvertCase(upFilename), upReference); if (wxStrcmp(upLabel, _T("contents")) == 0) { // TexOutput(_T("")); TexOutput(buf); // TexOutput(_T("")); } else TexOutput(buf); } /* * << button * */ if (previousLabel && previousFilename) { if (PrimaryAnchorOfTheFile(previousFilename, previousLabel)) wxSnprintf(buf, sizeof(buf), _T("%s "), ConvertCase(previousFilename), backReference); else wxSnprintf(buf, sizeof(buf), _T("%s "), ConvertCase(previousFilename), previousLabel, backReference); if (wxStrcmp(previousLabel, _T("contents")) == 0) { // TexOutput(_T("")); TexOutput(buf); // TexOutput(_T("")); } else TexOutput(buf); } else { // A placeholder so the buttons don't keep moving position wxSnprintf(buf, sizeof(buf), _T("%s "), backReference); TexOutput(buf); } wxChar *nextLabel = NULL; wxChar *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) { if (PrimaryAnchorOfTheFile(nextFilename, nextLabel)) wxSnprintf(buf, sizeof(buf), _T("%s "), ConvertCase(nextFilename), forwardReference); else wxSnprintf(buf, sizeof(buf), _T("%s "), ConvertCase(nextFilename), nextLabel, forwardReference); TexOutput(buf); } else { // A placeholder so the buttons don't keep moving position wxSnprintf(buf, sizeof(buf), _T("%s "), forwardReference); TexOutput(buf); } /* * Horizontal rule to finish it off nicely. * */ TexOutput(_T("
")); TexOutput(_T("
\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 wxChar *ParseColourString(wxChar *bkStr, bool *isPicture) { static wxChar resStr[300]; wxStrcpy(resStr, bkStr); wxStringTokenizer tok(resStr, _T(";"), wxTOKEN_STRTOK); if (tok.HasMoreTokens()) { wxString token1 = tok.GetNextToken(); if (!tok.HasMoreTokens()) { *isPicture = true; return resStr; } else { wxString token2 = tok.GetNextToken(); *isPicture = false; if (tok.HasMoreTokens()) { wxString token3 = tok.GetNextToken(); // Now convert 3 strings into decimal numbers, and then hex numbers. int red = wxAtoi(token1.c_str()); int green = wxAtoi(token2.c_str()); int blue = wxAtoi(token3.c_str()); wxStrcpy(resStr, _T("#")); wxChar buf[3]; DecToHex(red, buf); wxStrcat(resStr, buf); DecToHex(green, buf); wxStrcat(resStr, buf); DecToHex(blue, buf); wxStrcat(resStr, buf); return resStr; } else return NULL; } } else return NULL; } void OutputFont(void) { // Only output if explicitly requested by htmlFaceName= directive in // tex2rtf.ini. Otherwise do NOT set the font because we want to use browser's // default font: if (htmlFaceName) { // Output TexOutput(_T("\n")); } } // Output start of block void OutputBodyStart(void) { TexOutput(_T("\n\n")); OutputFont(); } void HTMLHead() { TexOutput(_T("")); if (htmlStylesheet) { TexOutput(_T("")); } }; void HTMLHeadTo(FILE* f) { if (htmlStylesheet) wxFprintf(f,_T(""),htmlStylesheet); else wxFprintf(f,_T("")); } // 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; wxChar *topicName = FindTopicName(GetNextChunk()); ReopenFile(&Chapters, &ChaptersName, topicName); AddTexRef(topicName, ChaptersName, ChapterNameString); SetCurrentChapterName(topicName, ChaptersName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(0, topicName, ChaptersName); SetCurrentOutput(Chapters); HTMLHead(); TexOutput(_T("")); OutputCurrentSection(); // Repeat section header TexOutput(_T("\n")); OutputBodyStart(); wxChar titleBuf[200]; if (truncateFilenames) wxSnprintf(titleBuf, sizeof(titleBuf), _T("%s.htm"), wxFileNameFromPath(FileRoot)); else wxSnprintf(titleBuf, sizeof(titleBuf), _T("%s_contents.html"), wxFileNameFromPath(FileRoot)); wxFprintf(Chapters, _T(""), topicName); AddBrowseButtons(_T(""), titleBuf, // Up lastTopic, lastFileName, // Last topic topicName, ChaptersName); // This topic if(PrimaryAnchorOfTheFile(ChaptersName, topicName)) wxFprintf(Contents, _T("\n
  • "), ConvertCase(ChaptersName)); else wxFprintf(Contents, _T("\n
  • "), ConvertCase(ChaptersName), topicName); if (htmlFrameContents && FrameContents) { SetCurrentOutput(FrameContents); if(PrimaryAnchorOfTheFile(ChaptersName, topicName)) wxFprintf(FrameContents, _T("\n
  • "), ConvertCase(ChaptersName)); else wxFprintf(FrameContents, _T("\n
  • "), ConvertCase(ChaptersName), topicName); OutputCurrentSection(); wxFprintf(FrameContents, _T("\n")); } SetCurrentOutputs(Contents, Chapters); wxFprintf(Chapters, _T("\n

    ")); OutputCurrentSection(); wxFprintf(Contents, _T("\n")); wxFprintf(Chapters, _T("

    \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; wxChar *topicName = FindTopicName(GetNextChunk()); ReopenFile(&Sections, &SectionsName, topicName); AddTexRef(topicName, SectionsName, SectionNameString); SetCurrentSectionName(topicName, SectionsName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(1, topicName, SectionsName); SetCurrentOutput(Sections); HTMLHead(); TexOutput(_T("")); OutputCurrentSection(); TexOutput(_T("\n")); OutputBodyStart(); wxFprintf(Sections, _T(""), 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) { if(PrimaryAnchorOfTheFile(SectionsName, topicName)) wxFprintf(jumpFrom, _T("\n
  • "), ConvertCase(SectionsName)); else wxFprintf(jumpFrom, _T("\n
  • "), ConvertCase(SectionsName), topicName); } else { if(PrimaryAnchorOfTheFile(SectionsName, topicName)) wxFprintf(jumpFrom, _T("\n"), ConvertCase(SectionsName)); else wxFprintf(jumpFrom, _T("\n"), ConvertCase(SectionsName), topicName); } wxFprintf(Sections, _T("\n

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

    \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(_T("You cannot have a subsection before a section!")); } else { subsubsectionNo = 0; if (macroId != ltSUBSECTIONSTAR) subsectionNo ++; if ( combineSubSections && !subsectionStarted ) { fflush(Sections); // Read old .con file in at this point wxChar buf[256]; wxStrcpy(buf, CurrentSectionFile); wxStripExtension(buf); wxStrcat(buf, _T(".con")); FILE *fd = wxFopen(buf, _T("r")); if ( fd ) { int ch = getc(fd); while (ch != EOF) { wxPutc(ch, Sections); ch = getc(fd); } fclose(fd); } wxFprintf(Sections, _T("

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

    ")); OutputCurrentSection(); wxFprintf(Sections, _T("
    \n")); wxFprintf(Subsections, _T("

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

    ")); OutputCurrentSection(); wxFprintf(Sections, _T("

    \n")); SetCurrentOutput(SectionContentsFD); wxFprintf(SectionContentsFD, _T(""), topicName); OutputCurrentSection(); TexOutput(_T("
    \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(_T("You cannot have a subsubsection before a subsection!")); } else { if (macroId != ltSUBSUBSECTIONSTAR) subsubsectionNo ++; startedSections = true; wxChar *topicName = FindTopicName(GetNextChunk()); if ( !combineSubSections ) { SetCurrentOutput(NULL); ReopenFile(&Subsubsections, &SubsubsectionsName, topicName); AddTexRef(topicName, SubsubsectionsName, SubsubsectionNameString); SetCurrentSubsubsectionName(topicName, SubsubsectionsName); if (htmlWorkshopFiles) HTMLWorkshopAddToContents(3, topicName, SubsubsectionsName); SetCurrentOutput(Subsubsections); HTMLHead(); TexOutput(_T("")); OutputCurrentSection(); TexOutput(_T("\n")); OutputBodyStart(); wxFprintf(Subsubsections, _T(""), topicName); AddBrowseButtons(CurrentSubsectionName, CurrentSubsectionFile, // Up lastTopic, lastFileName, // Last topic topicName, SubsubsectionsName); // This topic SetCurrentOutputs(Subsections, Subsubsections); if(PrimaryAnchorOfTheFile(SubsubsectionsName, topicName)) wxFprintf(Subsections, _T("\n"), ConvertCase(SubsubsectionsName)); else wxFprintf(Subsections, _T("\n"), ConvertCase(SubsubsectionsName), topicName); wxFprintf(Subsubsections, _T("\n

    ")); OutputCurrentSection(); wxFprintf(Subsections, _T("
    \n")); wxFprintf(Subsubsections, _T("

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

    ")); OutputCurrentSection(); wxFprintf(Sections, _T("

    \n")); /* TODO: where do we put subsubsection contents entry - indented, with subsection entries? SetCurrentOutput(SectionContentsFD); wxFprintf(SectionContentsFD, "", topicName); OutputCurrentSection(); TexOutput(_T("
    ")); */ 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(_T("void")); break; case ltHARDY: if (start) TexOutput(_T("HARDY")); break; case ltWXCLIPS: if (start) TexOutput(_T("wxCLIPS")); break; case ltAMPERSAND: if (start) TexOutput(_T("&")); break; case ltSPECIALAMPERSAND: { if (start) { if (inTabular) { // End cell, start cell TexOutput(_T("
    ")); // Start new row and cell, setting alignment for the first cell. if (currentColumn < noColumns) currentColumn ++; wxChar buf[100]; if (TableData[currentColumn].justification == 'c') wxSnprintf(buf, sizeof(buf), _T("\n")); else if (TableData[currentColumn].justification == 'r') wxSnprintf(buf, sizeof(buf), _T("\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); wxSnprintf(buf, sizeof(buf), _T(""), pixels); } else wxSnprintf(buf, sizeof(buf), _T("\n")); TexOutput(buf); OutputFont(); } else TexOutput(_T("&")); } 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(_T("\n")); } else TexOutput(_T("
    \n")); } break; } case ltROW: case ltRULEDROW: { if (start) { currentColumn = 0; // Start new row and cell, setting alignment for the first cell. wxChar buf[100]; if (TableData[currentColumn].justification == 'c') wxSnprintf(buf, sizeof(buf), _T("\n")); else if (TableData[currentColumn].justification == 'r') wxSnprintf(buf, sizeof(buf), _T("\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); wxSnprintf(buf, sizeof(buf), _T("\n"), pixels); } else wxSnprintf(buf, sizeof(buf), _T("\n")); TexOutput(buf); OutputFont(); } else { // End cell and row // Start new row and cell TexOutput(_T("
    \n\n")); } break; } // HTML-only: break until the end of the picture (both margins are clear). case ltBRCLEAR: { if (start) TexOutput(_T("
    ")); break; } case ltRTFSP: // Explicit space, RTF only break; case ltSPECIALTILDE: { if (start) { #if (1) // if(inVerbatim) TexOutput(_T("~")); #else TexOutput(_T(" ")); #endif } break; } case ltINDENTED : { if ( start ) TexOutput(_T("
        \n")); else TexOutput(_T("
    \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(_T("
      \n")); break; case LATEX_ENUMERATE: TexOutput(_T("
        \n")); break; case LATEX_DESCRIPTION: default: TexOutput(_T("
        \n")); break; } } else { indentLevel --; if (itemizeStack.GetFirst()) { ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.GetFirst()->GetData(); switch (struc->listType) { case LATEX_ITEMIZE: TexOutput(_T("
    \n")); break; case LATEX_ENUMERATE: TexOutput(_T("\n")); break; case LATEX_DESCRIPTION: default: TexOutput(_T("\n")); break; } delete struc; delete itemizeStack.GetFirst(); } } break; } case ltTWOCOLLIST : { if ( start ) TexOutput(_T("\n\n")); else { TexOutput(_T("\n
    \n")); // DHS TwoColWidthA = -1; TwoColWidthB = -1; } break; } case ltPAR: { if (start) TexOutput(_T("

    \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(_T("")); } else TexOutput(_T("")); break; } */ case ltVERB: { if (start) TexOutput(_T("")); else TexOutput(_T("")); break; } case ltVERBATIM: { if (start) { wxChar buf[100]; wxSnprintf(buf, sizeof(buf), _T("

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

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

    ")); TexOutput(_T("

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

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

    ")); TraverseChildrenFromChunk(DocumentAuthor); TexOutput(_T("

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

    ")); TraverseChildrenFromChunk(DocumentDate); TexOutput(_T("

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

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


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

    \n")); TexOutput(_T("

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

    ")); TexOutput(_T("

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

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

    ")); TraverseChildrenFromChunk(DocumentAuthor); TexOutput(_T("

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

    ")); TraverseChildrenFromChunk(DocumentDate); TexOutput(_T("

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

    \n")); TexOutput(_T("


    \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(_T("\n")); } break; } case ltHRULE: { if (start) { TexOutput(_T("


    \n")); } break; } case ltRULE: { if (start) { TexOutput(_T("
    \n")); } break; } case ltTABLEOFCONTENTS: { if (start) { // NB: if this is uncommented, the table of contents // completely disappears. If left commented, it's in the wrong // place. //fflush(Titlepage); FILE *fd = wxFopen(ContentsName, _T("r")); if (fd) { int ch = getc(fd); while (ch != EOF) { wxPutc(ch, Titlepage); ch = getc(fd); } fclose(fd); fflush(Titlepage); } else { TexOutput(_T("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n")); OnInform(_T("Run Tex2RTF again to include contents page.")); } } break; } case ltLANGLEBRA: { if (start) TexOutput(_T("<")); break; } case ltRANGLEBRA: { if (start) TexOutput(_T(">")); break; } case ltQUOTE: case ltQUOTATION: { if (start) TexOutput(_T("
    ")); else TexOutput(_T("
    ")); break; } case ltCAPTION: case ltCAPTIONSTAR: { if (start) { if (inTabular) TexOutput(_T("\n")); wxChar figBuf[40]; if ( inFigure ) { figureNo ++; if (DocumentStyle != LATEX_ARTICLE) wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d.%d: "), FigureNameString, chapterNo, figureNo); else wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d: "), FigureNameString, figureNo); } else { tableNo ++; if (DocumentStyle != LATEX_ARTICLE) wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d.%d: "), TableNameString, chapterNo, tableNo); else wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d: "), TableNameString, tableNo); } TexOutput(figBuf); } else { if (inTabular) TexOutput(_T("\n\n")); wxChar *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(_T("ß")); 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; } } /* CheckTypeRef() should be called at of argument which usually is type declaration which propably contains name of documented class examples: HTMLOnArgument - ltFUNC, - ltPARAM - ltCPARAM checks: GetArgData() if contains Type Declaration and can be referenced to some file prints: beforetypeafter returns: false - if no reference was found true - if reference was found and HREF printed */ static bool CheckTypeRef() { wxString typeDecl = GetArgData(); if( !typeDecl.empty() ) { typeDecl.Replace(wxT("\\"),wxT("")); wxString label = typeDecl; label.Replace(wxT("const"),wxT("")); label.Replace(wxT("virtual"),wxT("")); label.Replace(wxT("static"),wxT("")); label.Replace(wxT("extern"),wxT("")); label = label.BeforeFirst('&'); label = label.BeforeFirst(wxT('*')); label = label.BeforeFirst(wxT('\\')); label.Trim(true); label.Trim(false); wxString typeName = label; label.MakeLower(); TexRef *texRef = FindReference((wxChar*)label.c_str()); if (texRef && texRef->refFile && wxStrcmp(texRef->refFile, _T("??")) != 0) { int a = typeDecl.Find(typeName); wxString before = typeDecl.Mid( 0, a ); wxString after = typeDecl.Mid( a+typeName.Length() ); //wxFprintf(stderr,wxT("%s <%s> %s to ... %s#%s !!!!\n"), // before.c_str(), // typeName.c_str(), // after.c_str(), // texRef->refFile,label.c_str()); TexOutput(before); TexOutput(_T("refFile); TexOutput(_T("#")); TexOutput(label); TexOutput(wxT("\">")); TexOutput(typeName); TexOutput(wxT("")); TexOutput(after); return true; } else { //wxFprintf(stderr,wxT("'%s' from (%s) -> label %s NOT FOUND\n"), // typeName.c_str(), // typeDecl.c_str(), // label.c_str()); return false; } } return false; } // 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; } case ltFUNC: { if (start && (arg_no == 1)) { TexOutput(_T("")); if( CheckTypeRef() ) { TexOutput(_T(" ")); return false; } } if (!start && (arg_no == 1)) TexOutput(_T("
    ")); if (start && (arg_no == 2)) { if (!suppressNameDecoration) TexOutput(_T("")); currentMember = GetArgChunk(); } if (!start && (arg_no == 2)) { if (!suppressNameDecoration) TexOutput(_T("")); } if (start && (arg_no == 3)) TexOutput(_T("(")); if (!start && (arg_no == 3)) TexOutput(_T(")")); break; } case ltCLIPSFUNC: { if (start && (arg_no == 1)) TexOutput(_T("")); if (!start && (arg_no == 1)) TexOutput(_T(" ")); if (start && (arg_no == 2)) { if (!suppressNameDecoration) TexOutput(_T("( ")); currentMember = GetArgChunk(); } if (!start && (arg_no == 2)) { } if (!start && (arg_no == 3)) TexOutput(_T(")")); break; } case ltPFUNC: { if (!start && (arg_no == 1)) TexOutput(_T(" ")); if (start && (arg_no == 2)) TexOutput(_T("(*")); if (!start && (arg_no == 2)) TexOutput(_T(")")); if (start && (arg_no == 2)) currentMember = GetArgChunk(); if (start && (arg_no == 3)) TexOutput(_T("(")); if (!start && (arg_no == 3)) TexOutput(_T(")")); break; } case ltPARAM: case ltCPARAM: { const wxChar* pend = macroId == ltCPARAM ? _T("
    ") : _T(""); if( arg_no == 1) { if( start ) { TexOutput(_T("")); if( CheckTypeRef() ) { TexOutput(pend); return false; } } else { TexOutput(pend); } } if (start && (arg_no == 2)) { TexOutput(_T("")); } if (!start && (arg_no == 2)) { TexOutput(_T("")); } break; } case ltMEMBER: { if (!start && (arg_no == 1)) TexOutput(_T(" ")); if (start && (arg_no == 2)) currentMember = GetArgChunk(); break; } case ltREF: { if (start) { wxChar *sec = NULL; wxChar *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(_T("")); if (helpRefText) TraverseChildrenFromChunk(helpRefText); TexOutput(_T("")); } 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) { wxChar *refName = GetArgData(); wxChar *refFilename = NULL; if (refName) { TexRef *texRef = FindReference(refName); if (texRef) { if (texRef->refFile && wxStrcmp(texRef->refFile, _T("??")) != 0) refFilename = texRef->refFile; TexOutput(_T("refFile, refName)) { TexOutput(_T("#")); TexOutput(refName); } } TexOutput(_T("\">")); if (helpRefText) TraverseChildrenFromChunk(helpRefText); TexOutput(_T("")); } else { if (helpRefText) TraverseChildrenFromChunk(helpRefText); if (!ignoreBadRefs) TexOutput(_T(" (REF NOT FOUND)")); // for launching twice do not warn in preparation pass if ((passNumber == 1 && !runTwice) || (passNumber == 2 && runTwice)) { wxString errBuf; errBuf.Printf(_T("Warning: unresolved reference '%s'"), refName); OnInform((wxChar *)errBuf.c_str()); } } } else TexOutput(_T("??")); } return false; } break; } case ltIMAGE: case ltIMAGEL: case ltIMAGER: case ltPSBOXTO: { if (arg_no == 2) { if (start) { wxChar *alignment = _T(""); if (macroId == ltIMAGEL) alignment = _T(" align=left"); else if (macroId == ltIMAGER) alignment = _T(" align=right"); // Try to find an XBM or GIF image first. wxChar *filename = copystring(GetArgData()); wxChar buf[500]; wxStrcpy(buf, filename); StripExtension(buf); wxStrcat(buf, _T(".xbm")); wxString f = TexPathList.FindValidPath(buf); if (f == _T("")) // Try for a GIF instead { wxStrcpy(buf, filename); StripExtension(buf); wxStrcat(buf, _T(".gif")); f = TexPathList.FindValidPath(buf); } if (f == _T("")) // Try for a JPEG instead { wxStrcpy(buf, filename); StripExtension(buf); wxStrcat(buf, _T(".jpg")); f = TexPathList.FindValidPath(buf); } if (f == _T("")) // Try for a PNG instead { wxStrcpy(buf, filename); StripExtension(buf); wxStrcat(buf, _T(".png")); f = TexPathList.FindValidPath(buf); } if (f != _T("")) { wxChar *inlineFilename = copystring(f); #if 0 wxChar *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 && (wxStrcmp(inlineFilename, originalFilename) != 0)) { TexOutput(_T("")); TexOutput(_T("")); } else #endif { TexOutput(_T("")); delete[] inlineFilename; } } else { // Last resort - a link to a PS file. TexOutput(_T("Picture\n")); wxSnprintf(buf, sizeof(buf), _T("Warning: could not find an inline XBM/GIF for %s."), filename); OnInform(buf); } } } return false; } // First arg is PSBOX spec (ignored), second is image file, third is map name. case ltIMAGEMAP: { static wxChar *imageFile = NULL; if (start && (arg_no == 2)) { // Try to find an XBM or GIF image first. wxChar *filename = copystring(GetArgData()); wxChar buf[500]; wxStrcpy(buf, filename); StripExtension(buf); wxStrcat(buf, _T(".xbm")); wxString f = TexPathList.FindValidPath(buf); if (f == _T("")) // Try for a GIF instead { wxStrcpy(buf, filename); StripExtension(buf); wxStrcat(buf, _T(".gif")); f = TexPathList.FindValidPath(buf); } if (f == _T("")) { wxChar buf[300]; wxSnprintf(buf, sizeof(buf), _T("Warning: could not find an inline XBM/GIF for %s."), filename); OnInform(buf); } delete[] filename; if (imageFile) delete[] imageFile; imageFile = NULL; if (!f.empty()) { 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 wxChar buf[256]; wxStrcpy(buf, imageFile); StripExtension(buf); wxStrcat(buf, _T(".shg")); wxString f = TexPathList.FindValidPath(buf); if (f != _T("")) { // The default HTML file to go to is THIS file (so a no-op) SHGToMap((wxChar *)f.c_str(), currentFileName); } wxChar *mapName = GetArgData(); TexOutput(_T("")); TexOutput(_T("

    ")); delete[] imageFile; imageFile = NULL; } } return false; } 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(_T("\n

    ")); if (start && (arg_no == 2)) TexOutput(_T("
    ")); */ if (arg_no == 1) { if ( start ) { // DHS if (TwoColWidthA > -1) { wxChar buf[100]; wxSnprintf(buf, sizeof(buf), _T("\n\n"),TwoColWidthA); TexOutput(buf); } else { TexOutput(_T("\n\n")); } OutputFont(); } else TexOutput(_T("\n\n")); } if (arg_no == 2) { // DHS if ( start ) { if (TwoColWidthB > -1) { wxChar buf[100]; wxSnprintf(buf, sizeof(buf), _T("\n\n"),TwoColWidthB); TexOutput(buf); } else { TexOutput(_T("\n\n")); } OutputFont(); } else TexOutput(_T("\n\n")); } return true; } case ltNUMBEREDBIBITEM: { if (arg_no == 1 && start) { TexOutput(_T("\n
    ")); } if (arg_no == 2 && !start) TexOutput(_T("

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

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

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


    \n")); return true; } else TexOutput(_T("

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

    %s"), _T("bibliography"), ReferencesNameString); AddBrowseButtons(_T("contents"), titleBuf, // Up lastTopic, lastFileName, // Last topic _T("bibliography"), ChaptersName); // This topic SetCurrentOutputs(Contents, Chapters); if(PrimaryAnchorOfTheFile(ChaptersName, _T("bibliography"))) wxFprintf(Contents, _T("\n
  • "), ConvertCase(ChaptersName)); else wxFprintf(Contents, _T("\n
  • "), ConvertCase(ChaptersName), _T("bibliography")); wxFprintf(Contents, _T("%s\n"), ReferencesNameString); wxFprintf(Chapters, _T("
  • \n\n")); SetCurrentOutput(Chapters); return false; } if (!start && (arg_no == 2)) { } return true; } case ltINDEX: { /* Build up list of keywords associated with topics */ if (start) { // wxChar *entry = GetArgData(); wxChar buf[300]; OutputChunkToString(GetArgChunk(), buf); if (CurrentTopic) { AddKeyWordForTopic(CurrentTopic, buf, currentFileName); } } return false; } case ltFCOL: // case ltBCOL: { if (start) { switch (arg_no) { case 1: { wxChar *name = GetArgData(); wxChar buf2[10]; if (!FindColourHTMLString(name, buf2)) { wxStrcpy(buf2, _T("#000000")); wxChar buf[100]; wxSnprintf(buf, sizeof(buf), _T("Could not find colour name %s"), name); OnError(buf); } TexOutput(_T("")); break; } case 2: { return true; } default: break; } } else { if (arg_no == 2) TexOutput(_T("")); } return false; } 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; wxChar *str = GetArgData(); currentLevelNo = wxAtoi(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; } case 2: { return true; } default: break; } return true; } else { if (arg_no == 2) { CurrentOutput1 = oldLevelFile; } return true; } } default: return DefaultOnArgument(macroId, arg_no, start); } return true; } bool HTMLGo(void) { fileId = 0; inVerbatim = false; indentLevel = 0; inTabular = false; startRows = false; tableVerticalLineLeft = false; tableVerticalLineRight = false; noColumns = 0; if (!InputFile.empty() && !OutputFile.empty()) { // Do some HTML-specific transformations on all the strings, // recursively Text2HTML(GetTopLevelChunk()); wxChar buf[300]; if (truncateFilenames) wxSnprintf(buf, WXSIZEOF(buf), _T("%s.htm"), FileRoot); else wxSnprintf(buf, WXSIZEOF(buf), _T("%s_contents.html"), FileRoot); if (TitlepageName) delete[] TitlepageName; TitlepageName = copystring(buf); Titlepage = wxFopen(buf, _T("w")); if (truncateFilenames) wxSnprintf(buf, WXSIZEOF(buf), _T("%s_fc.htm"), FileRoot); else wxSnprintf(buf, WXSIZEOF(buf), _T("%s_fcontents.html"), FileRoot); contentsFrameName = copystring(buf); Contents = wxFopen(TmpContentsName, _T("w")); if (htmlFrameContents) { // FrameContents = wxFopen(TmpFrameContentsName, _T("w")); FrameContents = wxFopen(contentsFrameName, _T("w")); wxFprintf(FrameContents, _T("\n
      \n")); } if (!Titlepage || !Contents) { OnError(_T("Cannot open output file!")); return false; } AddTexRef(_T("contents"), wxFileNameFromPath(TitlepageName), ContentsNameString); wxFprintf(Contents, _T("

      %s

      \n"), ContentsNameString); wxFprintf(Contents, _T("

        \n")); SetCurrentOutput(Titlepage); if (htmlWorkshopFiles) HTMLWorkshopStartContents(); OnInform(_T("Converting...")); TraverseDocument(); wxFprintf(Contents, _T("
      \n\n")); // SetCurrentOutput(Titlepage); fclose(Titlepage); if (Contents) { // wxFprintf(Titlepage, _T("\n\n")); fclose(Contents); Contents = NULL; } if (FrameContents) { wxFprintf(FrameContents, _T("\n
    \n")); wxFprintf(FrameContents, _T("\n")); fclose(FrameContents); FrameContents = NULL; } if (Chapters) { wxFprintf(Chapters, _T("\n\n")); fclose(Chapters); Chapters = NULL; } if (Sections) { wxFprintf(Sections, _T("\n\n")); fclose(Sections); Sections = NULL; } if (Subsections && !combineSubSections) { wxFprintf(Subsections, _T("\n\n")); fclose(Subsections); Subsections = NULL; } if (Subsubsections && !combineSubSections) { wxFprintf(Subsubsections, _T("\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 = wxFopen(_T("title.tmp"), _T("w")); if (tmpTitle) { if (DocumentTitle) { SetCurrentOutput(tmpTitle); HTMLHead(); TexOutput(_T("\n")); TraverseChildrenFromChunk(DocumentTitle); TexOutput(_T("\n")); } else { SetCurrentOutput(tmpTitle); HTMLHeadTo(tmpTitle); if (contentsString) wxFprintf(tmpTitle, _T("%s\n\n"), contentsString); else wxFprintf(tmpTitle, _T("%s\n\n"), wxFileNameFromPath(FileRoot)); } // Output frame information if (htmlFrameContents) { wxChar firstFileName[300]; if (truncateFilenames) wxSnprintf(firstFileName, sizeof(firstFileName), _T("%s1.htm"), FileRoot); else wxStrcpy(firstFileName, gs_filenames[1].c_str()); wxFprintf(tmpTitle, _T("\n")); wxFprintf(tmpTitle, _T("\n"), ConvertCase(wxFileNameFromPath(contentsFrameName))); wxFprintf(tmpTitle, _T("\n"), ConvertCase(wxFileNameFromPath(firstFileName))); wxFprintf(tmpTitle, _T("\n")); wxFprintf(tmpTitle, _T("\n")); } // Output <BODY...> to temporary title page OutputBodyStart(); fflush(tmpTitle); // Concat titlepage FILE *fd = wxFopen(TitlepageName, _T("r")); if (fd) { int ch = getc(fd); while (ch != EOF) { wxPutc(ch, tmpTitle); ch = getc(fd); } fclose(fd); } wxFprintf(tmpTitle, _T("\n</FONT></BODY>\n")); if (htmlFrameContents) { wxFprintf(tmpTitle, _T("\n\n")); } wxFprintf(tmpTitle, _T("\n\n")); fclose(tmpTitle); if (wxFileExists(TitlepageName)) wxRemoveFile(TitlepageName); if (!wxRenameFile(_T("title.tmp"), TitlepageName)) { wxCopyFile(_T("title.tmp"), TitlepageName); wxRemoveFile(_T("title.tmp")); } } if (lastFileName) delete[] lastFileName; lastFileName = NULL; if (lastTopic) delete[] lastTopic; lastTopic = NULL; if (wxFileExists(ContentsName)) wxRemoveFile(ContentsName); if (!wxRenameFile(TmpContentsName, ContentsName)) { wxCopyFile(TmpContentsName, ContentsName); wxRemoveFile(TmpContentsName); } // Generate .htx file if requested if (htmlIndex) { wxChar htmlIndexName[300]; wxSnprintf(htmlIndexName, sizeof(htmlIndexName), _T("%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(wxChar *fname) { FILE *fd = wxFopen(fname, _T("w")); if (!fd) return; TopicTable.BeginFind(); wxHashTable::Node *node = TopicTable.Next(); while (node) { TexTopic *texTopic = (TexTopic *)node->GetData(); const wxChar *topicName = node->GetKeyString(); if (texTopic->filename && texTopic->keywords) { wxStringListNode *node1 = texTopic->keywords->GetFirst(); while (node1) { wxChar *s = (wxChar *)node1->GetData(); wxFprintf(fd, _T("%s|%s|%s\n"), topicName, texTopic->filename, s); node1 = node1->GetNext(); } } node = TopicTable.Next(); } fclose(fd); } // output .hpp, .hhc and .hhk files: void GenerateHTMLWorkshopFiles(wxChar *fname) { FILE *f; wxChar buf[300]; /* Generate project file : */ wxSnprintf(buf, sizeof(buf), _T("%s.hhp"), fname); f = wxFopen(buf, _T("wt")); wxFprintf(f, _T("[OPTIONS]\n") _T("Compatibility=1.1\n") _T("Full-text search=Yes\n") _T("Contents file=%s.hhc\n") _T("Compiled file=%s.chm\n") _T("Default Window=%sHelp\n") _T("Default topic=%s\n") _T("Index file=%s.hhk\n") _T("Title="), wxFileNameFromPath(fname), wxFileNameFromPath(fname), wxFileNameFromPath(fname), wxFileNameFromPath(TitlepageName), wxFileNameFromPath(fname) ); if (DocumentTitle) { SetCurrentOutput(f); TraverseChildrenFromChunk(DocumentTitle); } else wxFprintf(f, _T("(unknown)")); wxFprintf(f, _T("\n\n[WINDOWS]\n") _T("%sHelp=,\"%s.hhc\",\"%s.hhk\",\"%s\",,,,,,0x2420,,0x380e,,,,,0,,,"), wxFileNameFromPath(fname), wxFileNameFromPath(fname), wxFileNameFromPath(fname), wxFileNameFromPath(TitlepageName)); wxFprintf(f, _T("\n\n[FILES]\n")); wxFprintf(f, _T("%s\n"), wxFileNameFromPath(TitlepageName)); for (int i = 1; i <= fileId; i++) { if (truncateFilenames) wxSnprintf(buf, sizeof(buf), _T("%s%d.htm"), wxFileNameFromPath(FileRoot), i); else wxStrcpy(buf, wxFileNameFromPath(gs_filenames[i].c_str())); wxFprintf(f, _T("%s\n"), buf); } fclose(f); /* Generate index file : */ wxSnprintf(buf, sizeof(buf), _T("%s.hhk"), fname); f = wxFopen(buf, _T("wt")); wxFprintf(f, _T("\n") _T("\n")); HTMLHeadTo(f); wxFprintf(f, _T("\n") _T("\n") _T("\n") _T("\n") _T("\n") _T(" \n") _T("\n") _T("
      \n")); TopicTable.BeginFind(); wxHashTable::Node *node = TopicTable.Next(); while (node) { TexTopic *texTopic = (TexTopic *)node->GetData(); const wxChar *topicName = node->GetKeyString(); if (texTopic->filename && texTopic->keywords) { wxStringListNode *node1 = texTopic->keywords->GetFirst(); while (node1) { wxChar *s = (wxChar *)node1->GetData(); wxFprintf(f, _T("
    • \n") _T(" \n") _T(" \n") _T(" \n"), texTopic->filename, topicName, s); node1 = node1->GetNext(); } } node = TopicTable.Next(); } wxFprintf(f, _T("
    \n")); fclose(f); } static FILE *HTMLWorkshopContents = NULL; static int HTMLWorkshopLastLevel = 0; void HTMLWorkshopAddToContents(int level, wxChar *s, wxChar *file) { int i; if (level > HTMLWorkshopLastLevel) for (i = HTMLWorkshopLastLevel; i < level; i++) wxFprintf(HTMLWorkshopContents, _T("
      ")); if (level < HTMLWorkshopLastLevel) for (i = level; i < HTMLWorkshopLastLevel; i++) wxFprintf(HTMLWorkshopContents, _T("
    ")); SetCurrentOutput(HTMLWorkshopContents); wxFprintf(HTMLWorkshopContents, _T("
  • \n") _T(" \n") _T(" \n") _T(" \n")); HTMLWorkshopLastLevel = level; } void HTMLWorkshopStartContents() { wxChar buf[300]; wxSnprintf(buf, sizeof(buf), _T("%s.hhc"), FileRoot); HTMLWorkshopContents = wxFopen(buf, _T("wt")); HTMLWorkshopLastLevel = 0; wxFprintf(HTMLWorkshopContents, _T("\n") _T("\n")); HTMLHeadTo(HTMLWorkshopContents); wxFprintf(HTMLWorkshopContents, _T("\n") _T("\n") _T("\n") _T("\n") _T("\n") _T(" \n") _T("\n") _T("
      \n") _T("
    • \n") _T("\n") _T("\n\n"), wxFileNameFromPath(TitlepageName) ); } void HTMLWorkshopEndContents() { for (int i = HTMLWorkshopLastLevel; i >= 0; i--) wxFprintf(HTMLWorkshopContents, _T("
    \n")); fclose(HTMLWorkshopContents); } bool PrimaryAnchorOfTheFile( wxChar *file, wxChar *label ) { wxString file_label; file_label.Printf( HTML_FILENAME_PATTERN, FileRoot, label ); return file_label.IsSameAs( file , false ); }