📄 html.cc
字号:
/* html.cc Copyright (c) 1996 Roland Wunderling, Malte Zoeckler Copyright (c) 1998 Michael Meeks Copyright (c) 1998-2001 Dragos Acostachioaie This file is part of DOC++. DOC++ is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the license, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <assert.h>#include <ctype.h>#ifdef __BORLANDC__#include <dir.h>#endif#if defined(__VISUALC__) || defined(__WATCOMC__) || defined(__MINGW32__)#include <direct.h>#endif#include <errno.h>#include <iostream.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include "McDirectory.h"#include "McHashTable.h"#include "McSorter.h"#include "classgraph.h"#include "doc.h"#include "gifs.h"#include "java.h"#define max(a, b) ((a) > (b) ? (a) : (b))#define BGCOLOR "<BODY BGCOLOR=\"#ffffff\">\n"static McString header, footer;static char *GENERAL_NAME = "General";FILE *generalf;static char *docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n\n";static McString styleSheet;static McString indexHeader;static McString indexFooter;static McString hierHeader;static McString hierFooter;static McString generalHeader;static McString pageHeader;static McString pageFooter;static McString pageFooterJava;void writeTOCentry(FILE *f, Entry *e, bool memo, bool dup = false);int makedir(const char *d, int perm){#if defined(__BORLANDC__) || defined(__WATCOMC__) return mkdir(d);#else#if defined(__VISUALC__) || defined(__MINGW32__) return _mkdir(d);#else return mkdir(d, perm);#endif#endif}#define myisalnum(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c== '.' || c == '-')// Initializes HTML headersvoid buildHeaders(){ if(htmlStyleSheet.length() > 0) { styleSheet = " <LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\""; styleSheet += htmlStyleSheet; styleSheet += "\">\n"; } indexHeader = docType; indexHeader += "<HTML>\n" "<HEAD>\n"; indexHeader += _(" <TITLE>Table of Contents</TITLE>\n"); indexHeader += " <META NAME=\"GENERATOR\" CONTENT=\"DOC++ " DOCXX_VERSION "\">\n"; indexHeader += styleSheet; indexHeader += "</HEAD>\n" BGCOLOR; hierHeader = docType; hierHeader += "<HTML>\n" "<HEAD>\n"; hierHeader += _(" <TITLE>Hierarchy of Classes</TITLE>\n"); hierHeader += " <META NAME=\"GENERATOR\" CONTENT=\"DOC++ " DOCXX_VERSION "\">\n"; hierHeader += styleSheet; hierHeader += "</HEAD>\n" BGCOLOR; generalHeader = docType; generalHeader += "<HTML>\n"; generalHeader += _("<HEAD>\n <TITLE>General Bits</TITLE>\n"); generalHeader += " <META NAME=\"GENERATOR\" CONTENT=\"DOC++ " DOCXX_VERSION "\">\n"; generalHeader += styleSheet; generalHeader += "</HEAD>\n" BGCOLOR; pageHeader += BGCOLOR;}// Initializes HTML footersvoid buildFooters(){ bool generateClassGraphs = !noClassGraph && relevantClassGraphs(root); if(generateClassGraphs) { indexFooter = "<P><I><A HREF=\"HIER"; indexFooter += htmlSuffix; indexFooter += _("\">Hierarchy of classes</A></I></P>"); } hierFooter = "<P><I><A HREF=\"index"; hierFooter += htmlSuffix; hierFooter += _("\">Alphabetic index</A></I></P>"); pageFooter = "<P><I><A HREF=\"index"; pageFooter += htmlSuffix; pageFooter += _("\">Alphabetic index</A></I>"); if(generateClassGraphs) { pageFooter += " <I><A HREF=\"HIER"; pageFooter += htmlSuffix; pageFooter += _("\">Hierarchy of classes</A></I>"); } pageFooter += "</P>"; pageFooterJava = "<P><I><A HREF=\"index"; pageFooterJava += htmlSuffix; pageFooterJava += _("\">Alphabetic index</A></I>"); if(generateClassGraphs) { pageFooterJava += " <I><A HREF=\"HIER"; pageFooterJava += htmlSuffix; pageFooterJava += _("\">HTML hierarchy of classes</A>"); pageFooterJava += _(" or <A HREF=\"HIERjava"); pageFooterJava += htmlSuffix; pageFooterJava += "\">Java</A></I>"; } pageFooterJava += "</P>";}McString makeFileName(const McString& str, Entry *e){ static McHashTable<char *,int> files(1); McString s, ls; char buf[40]; int i, l = str.length(); int odd = 0; // An unusual thing ... // the user already decided what filename to use, so exit quickly if(e->fileName.length() > 0) { e->fileName += htmlSuffix; return e->fileName; } for(i = 0; i < l; i++) if(myisalnum(str[i])) { char c = str[i]; s += c; if(c >= 'A' && c <= 'Z') c += (((int)'a') - 'A'); ls += c; } char *tmp = strdup(ls.c_str()); int *val = files.insert(tmp); if(*val > 1) { free(tmp); s += '.'; sprintf(buf, "%d", *val); s += buf; odd = 1; } (*val)++; s += htmlSuffix;#ifdef DEBUG if(verb && odd) { fprintf(stderr, _("Warning: weird file name `%s'\n"), s.c_str()); e->dump(stdout); }#endif return s;}enum _outType{ DOC = 1, MEMO = 2};void htmlComment(FILE *f, Entry *e, int t){ bool done = false; char start[] = "<BLOCKQUOTE>"; char end[] = "</BLOCKQUOTE>"; if((t & DOC) && e->doc.length() > 1) { fprintf(f, "%s%s%s\n", start, (e->hdoc), end); done = true; } if((t & MEMO) && !done && e->memo.length() > 1) fprintf(f, "%s%s%s\n", start, (e->hmemo), end);}int subEntryIsToBeDocumented(Entry *entry){ bool toBeDocumented = false; if(entry->protection != PRIV || withPrivate) { if(entry->retrn.size() || entry->field.size() || entry->param.size() || entry->author.length() || entry->see.size() || entry->version.length()) toBeDocumented = true; if(entry->doc.length() > entry->memo.length() || (entry->doc.length() == entry->memo.length() && entry->doc == entry->memo)) toBeDocumented = true; if(alwaysPrintDocSection) toBeDocumented = true; } return toBeDocumented;}void copyright(FILE *f){ fprintf(f, "<HR>\n"); if(footer.length() <= 0 && ownFooter.length() == 0) { fprintf(f, "<BR>\n"); fprintf(f, _("This page was generated with the help of <A HREF=\"http://docpp.sourceforge.net\">DOC++</A>.\n")); fprintf(f, "</BODY>\n"); fprintf(f, "</HTML>\n"); } else fprintf(f, "%s", footer.c_str());}// Writes classgraphs. Either as text-graphs or as java-graphs.class ClassGraphWriter{ public: static void writeJava(FILE *f, Entry *e, bool directOnly = true); static void writeText(FILE *f, Entry *e); static void write(FILE *f, Entry *e); static void writeImplements(FILE *f, Entry *e);};struct MemberWriterListEntry { Entry *entry; int links; int withSub;};// This class writes members.class MemberWriter{ public: MemberWriter() { f = NULL; } protected: McString heading; int first; FILE *f; McDArray<MemberWriterListEntry> list; virtual const char *startString() { return "<P><DL>"; }; virtual const char *endString() { return "</DL></P>"; }; virtual void showSubMembers(Entry *); virtual void writeMember(Entry *e, bool links, bool withSub = true); class EntryCompare { public: int operator()(const MemberWriterListEntry& l1, const MemberWriterListEntry& l2) { return strcmp(l1.entry->fullName.c_str(), l2.entry->fullName.c_str()); } }; public: virtual void sort() { EntryCompare comp; if(list.size()) ::sort((MemberWriterListEntry *)list, list.size(), comp, 0); } virtual void startList(FILE *f, char *heading, bool withLinks); virtual void addMember(Entry *e, bool links, bool withSub = true) { MemberWriterListEntry le; le.entry = e; le.links = links; le.withSub = withSub; list.append(le); } virtual void endList(); virtual ~MemberWriter() {};};class MemberWriterTable : public MemberWriter{ protected: virtual const char *startString() { return (withBorders ? "<P><TABLE BORDER>" : "<P><TABLE>"); }; virtual const char *endString() { return "</TABLE></P>"; }; virtual void writeMember(Entry *e, bool links, bool withSub = true);};class TOClist;struct TOCListEntry { Entry *e; TOClist *tl; const char *name;};// Renamed from `SortedList' as far too specific now...class TOClist : public MemberWriter{ protected: McDArray<TOCListEntry> list; public: virtual void sort() { EntryCompare comp; int lp; if(list.size() > 1) ::sort((TOCListEntry *)list, list.size(), comp, 0); // Sort subsections for(lp = 0; lp < list.size(); lp++) if(list[lp].tl) list[lp].tl->sort(); } class EntryCompare { public: int operator()(TOCListEntry& l1, TOCListEntry& l2) { return strcmp(l1.name, l2.name); } }; void addEntry(Entry *entry, TOClist *tl); void write(FILE *f); int size() { return list.size(); } ~TOClist();};void TOClist::write(FILE *f){ // Resolve conflicts, get meaningful data from WriteTOCentry // (f, entry, 1), and go for it... merge writeTOCEntry into this ? // As a further burden, try and merge duplicate ClassName link references // ALSO, do sub lists int i, last_collision = 0, size = list.size(), conf; bool inUL = false; for(i = 0; i < size; i++) { TOCListEntry *le, *nle; le = &list[i]; if(i < size - 1) nle = &list[i + 1]; else nle = 0; // Skip identical entries (e.g. loads of constructors in a class) // --- // Global functions that are overloaded get seen as indentical, // but they in fact have different documentation, which is why we // check for fileName as well <cpbotha@bigfoot.com> if(nle && le->name == nle->name && le->tl == nle->tl && le->e->fileName == nle->e->fileName) continue; // Detect identicaly named entries (e.g. lots of next()) // --- // See comment above about overloaded global functions // <cpbotha@bigfoot.com> conf = nle && le->e->name == nle->e->name && le->e->fileName == nle->e->fileName; if(conf != last_collision && conf) { fprintf(f, "<LI><B>%s:</B>\n<UL>\n", le->e->name.c_str()); inUL = true; } fprintf(f, "<LI>"); writeTOCentry(f, le->e, true, (conf | last_collision)); if(conf != last_collision && !conf) { fprintf(f, "</UL>\n"); inUL = false; } if(le->tl && le->tl->size() > 0) // A dreaded sub-list e.g. package list { fprintf(f, "<UL>"); le->tl->write(f); fprintf(f, "</UL>"); } last_collision = conf; } if(inUL) // Some odd thing happened at the end of the list... fprintf(f, "</UL>\n");}void TOClist::addEntry(Entry *entry, TOClist *tl){ TOCListEntry le; // don't show class members in the TOC... due to popular demand // do the same with structure and namespace members if(!showMembersInTOC) if((entry->parent->section & CLASS_SEC) || entry->parent->section == NAMESPACE_SEC || (entry->parent->section == INTERFACE_SEC && language == LANG_IDL) || entry->parent->section == UNION_SEC || entry->parent->section == TYPEDEF_SEC || (entry->parent->section == MANUAL_SEC && entry->parent != root)) return; le.e = entry; le.tl = tl; le.name = entry->fullName.c_str(); list.append(le);}TOClist::~TOClist(){ int i; for(i = 0; i < list.size(); i++) if(list[i].tl) free(list[i].tl);}class HIERlist;struct HIERListEntry { Entry *e; HIERlist *hl; const char *name;};class HIERlist : public MemberWriter{ protected: McDArray<HIERListEntry> list; public: virtual void sort() { EntryCompare comp; int i; if(list.size() > 1) ::sort((HIERListEntry *)list, list.size(), comp, 0); // Sort subentries for(i = 0; i < list.size(); i++) if(list[i].hl) list[i].hl->sort(); } class EntryCompare { public: int operator()(HIERListEntry& l1, HIERListEntry& l2) { return strcmp(l1.name, l2.name); } }; void addEntry(Entry *entry, HIERlist *hl); void write(FILE *f); int size() { return list.size(); } ~HIERlist();};void HIERlist::write(FILE *f){ int i; for(i = 0; i < size(); i++) { fprintf(f, "\n<LI>"); writeTOCentry(f, list[i].e, false); if(list[i].hl) { fprintf(f, "<UL>\n"); list[i].hl->write(f); fprintf(f, "</UL>\n"); } }}void HIERlist::addEntry(Entry *entry, HIERlist *hl){ HIERListEntry le; le.e = entry; le.hl = hl; le.name = entry->name.c_str(); list.append(le);}HIERlist::~HIERlist()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -