📄 htmlutil.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// 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,v 1.34 2006/09/05 20:44:44 VZ Exp $// 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 <stdio.h>#define HTML_FILENAME_PATTERN _T("%s_%s.html")#if !WXWIN_COMPATIBILITY_2_4static inline wxChar* copystring(const wxChar* s) { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }#endifextern 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 parsingwxChar *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/listoftablesstatic 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</FONT></BODY></HTML>\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("<HTML>\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 -> <P>. * */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("<P>\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 = "<img align=center src=\"contents.gif\" BORDER=0 ALT=\"Contents\">"; contentsReference = contentsReferenceBuf; wxSnprintf(contentsReference, sizeof(contentsReferenceBuf), _T("<img align=center src=\"%s\" BORDER=0 ALT=\"Contents\">"), ConvertCase(_T("contents.gif"))); } wxChar *upReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) upReference = UpNameString; else {// upReference = "<img align=center src=\"up.gif\" ALT=\"Up\">"; upReference = upReferenceBuf; wxSnprintf(upReference, sizeof(upReferenceBuf), _T("<img align=center src=\"%s\" BORDER=0 ALT=\"Up\">"), ConvertCase(_T("up.gif"))); } wxChar *backReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) backReference = _T("<<"); else {// backReference = "<img align=center src=\"back.gif\" ALT=\"Previous\">"; backReference = backReferenceBuf; wxSnprintf(backReference, sizeof(backReferenceBuf), _T("<img align=center src=\"%s\" BORDER=0 ALT=\"Previous\">"), ConvertCase(_T("back.gif"))); } wxChar *forwardReference; // no need to initialize because always assigned below if (htmlBrowseButtons == HTML_BUTTONS_TEXT) forwardReference = _T(">>"); else {// forwardReference = "<img align=center src=\"forward.gif\" ALT=\"Next\">"; forwardReference = forwardReferenceBuf; wxSnprintf(forwardReference, sizeof(forwardReferenceBuf), _T("<img align=center src=\"%s\" BORDER=0 ALT=\"Next\">"), ConvertCase(_T("forward.gif"))); } TexOutput(_T("<CENTER>")); wxChar buf[200]; /* * Contents button * */ if (truncateFilenames) { wxChar buf1[80]; wxStrcpy(buf1, ConvertCase(wxFileNameFromPath(FileRoot))); wxSnprintf(buf, sizeof(buf), _T("\n<A HREF=\"%s.%s\">%s</A> "), buf1, ConvertCase(_T("htm")), contentsReference); } else { wxChar buf1[80]; wxStrcpy(buf1, ConvertCase(wxFileNameFromPath(FileRoot))); wxSnprintf(buf, sizeof(buf), _T("\n<A HREF=\"%s%s\">%s</A> "), buf1, ConvertCase(_T("_contents.html")), contentsReference); }// TexOutput(_T("<NOFRAMES>")); TexOutput(buf);// TexOutput(_T("</NOFRAMES>")); /* * Up button * */ if (upLabel && upFilename) { if ( (wxStrlen(upLabel) > 0) && !PrimaryAnchorOfTheFile(upFilename, upLabel) ) wxSnprintf(buf, sizeof(buf), _T("<A HREF=\"%s#%s\">%s</A> "), ConvertCase(upFilename), upLabel, upReference); else wxSnprintf(buf, sizeof(buf), _T("<A HREF=\"%s\">%s</A> "), ConvertCase(upFilename), upReference); if (wxStrcmp(upLabel, _T("contents")) == 0) {// TexOutput(_T("<NOFRAMES>")); TexOutput(buf);// TexOutput(_T("</NOFRAMES>")); } else TexOutput(buf); } /* * << button * */ if (previousLabel && previousFilename) { if (PrimaryAnchorOfTheFile(previousFilename, previousLabel)) wxSnprintf(buf, sizeof(buf), _T("<A HREF=\"%s\">%s</A> "), ConvertCase(previousFilename), backReference); else wxSnprintf(buf, sizeof(buf), _T("<A HREF=\"%s#%s\">%s</A> "), ConvertCase(previousFilename), previousLabel, backReference); if (wxStrcmp(previousLabel, _T("contents")) == 0) {// TexOutput(_T("<NOFRAMES>")); TexOutput(buf);// TexOutput(_T("</NOFRAMES>")); } else TexOutput(buf); } else { // A placeholder so the buttons don't keep moving position wxSnprintf(buf, sizeof(buf), _T("%s "), backReference); TexOutput(buf); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -