summaryrefslogtreecommitdiff
path: root/cpp/src/slice2html/Gen.cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2007-01-08 08:02:53 +0000
committerMichi Henning <michi@zeroc.com>2007-01-08 08:02:53 +0000
commita83f822a46fa5f9a26bf52575d9b0be4748ded96 (patch)
tree998b3069bf7a2dea646a9ddc7e773b1a51019c4b /cpp/src/slice2html/Gen.cpp
parentAdded ObejctAdapter::destroy (diff)
downloadice-a83f822a46fa5f9a26bf52575d9b0be4748ded96.tar.bz2
ice-a83f822a46fa5f9a26bf52575d9b0be4748ded96.tar.xz
ice-a83f822a46fa5f9a26bf52575d9b0be4748ded96.zip
Added TOC generation to slice2html.
Diffstat (limited to 'cpp/src/slice2html/Gen.cpp')
-rw-r--r--cpp/src/slice2html/Gen.cpp356
1 files changed, 266 insertions, 90 deletions
diff --git a/cpp/src/slice2html/Gen.cpp b/cpp/src/slice2html/Gen.cpp
index 7a8e8847f02..ccab207775f 100644
--- a/cpp/src/slice2html/Gen.cpp
+++ b/cpp/src/slice2html/Gen.cpp
@@ -33,7 +33,9 @@ namespace Slice
void
generate(const UnitPtr& unit, const ::std::string& dir,
- const ::std::string& header, const ::std::string& footer, unsigned indexCount, unsigned warnSummary)
+ const ::std::string& header, const ::std::string& footer,
+ const ::std::string& indexHeader, const ::std::string& indexFooter,
+ unsigned indexCount, unsigned warnSummary)
{
unit->mergeModules();
@@ -50,28 +52,34 @@ generate(const UnitPtr& unit, const ::std::string& dir,
GeneratorBase::warnSummary(warnSummary);
//
- // The types visitor first runs over the tree and records
+ // The file visitor first runs over the tree and records
// the names of all files in this documentation set.
// This information is used later to check whether a referenced
- // symbol is defined in this documentation set (as opposed to
- // being defined in an included fiel that is not part of this
+ // symbol is defined in this documentation set, as opposed to
+ // being defined in an included file that is not part of this
// documentation set. If the former, we can generate a link
// to the symbol; if the latter, we cannot.
//
Files files;
- TypesVisitor tv(files);
+ FileVisitor tv(files);
unit->visit(&tv, false);
//
- // Generate the main module index.
+ // Generate the start page.
//
- IndexVisitor iv(files);
- unit->visit(&iv, false);
+ StartPageVisitor spv(files);
+ unit->visit(&spv, false);
+
+ //
+ // Generate the table of contents.
+ //
+ TOCVisitor tocv(files, indexHeader, indexFooter);
+ unit->visit(&tocv, false);
//
// Generate the individual HTML pages.
//
- Visitor v(files);
+ PageVisitor v(files);
unit->visit(&v, false);
}
@@ -99,67 +107,26 @@ Slice::GeneratorBase::setOutputDir(const string& dir)
}
//
-// Set a header. If "header" is empty, use a default header.
+// Get the headers. If "header" is empty, use a default header.
// If a header file is specified, it is expected to end in <body>
// and to contain a "TITLE" placeholder line (in column 1, no leading
// or trailing white space). The actual document title is later substituted
// where that TITLE placeholder appears.
//
-
void
Slice::GeneratorBase::setHeader(const string& header)
{
- if(header.empty())
- {
- ostringstream hdr1;
- XMLOutput O1(hdr1);
- O1 << "<!-- Generated by Ice version " << ICE_STRING_VERSION << " -->";
- O1 << sp;
- O1 << nl << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">";
- O1 << se("html");
- O1 << se("head");
- O1 << se("title") << nl;
- _header1 = hdr1.str();
-
- // _header1 and _header2 store the bit preceding and following the title.
- // _header1, the title text, and _header2 are written by openDoc().
-
- ostringstream hdr2;
- XMLOutput O2(hdr2);
- O2.inc();
- O2.inc();
- O2 << nl << "</title>";
- O2.dec();
- O2 << nl << "</head>";
- O2 << nl << "<body>";
- _header2 = hdr2.str();
- }
- else
- {
- readFile(header, _header1, _header2);
- }
+ getHeaders(header, _header1, _header2);
}
//
-// Set a footer. If "footer" is empty, use a default footer.
+// Get the footer. If "footer" is empty, use a default footer.
// The footer is expected to start with </body>.
//
-
void
Slice::GeneratorBase::setFooter(const string& footer)
{
- ostringstream ftr;
- XMLOutput O(ftr);
- if(footer.empty())
- {
- O << " </body>";
- }
- else
- {
- O << readFile(footer);
- }
- O << nl << "</html>";
- _footer = ftr.str();
+ _footer = getFooter(footer);
}
//
@@ -168,7 +135,6 @@ Slice::GeneratorBase::setFooter(const string& footer)
// sub-index. (For example, with "ic" set to 3, we generate
// a sub-index only if, say, a structure has 3 or more members.
//
-
void
Slice::GeneratorBase::setIndexCount(int ic)
{
@@ -178,7 +144,6 @@ Slice::GeneratorBase::setIndexCount(int ic)
//
// If n > 0, we print a warning if a summary sentence exceeds n characters.
//
-
void
Slice::GeneratorBase::warnSummary(int n)
{
@@ -198,16 +163,32 @@ Slice::GeneratorBase::~GeneratorBase()
// Open a file for writing in the output directory (the output directory
// is created if necessary) and write the HTML header into the file.
//
-
void
-Slice::GeneratorBase::openDoc(const string& file, const string& title)
+Slice::GeneratorBase::openDoc(const string& file, const string& title, const string& header, const string& footer)
{
makeDir(_dir);
openStream(_dir + "/" + file);
- _out << _header1;
+ string h1;
+ string h2;
+ if(header.empty())
+ {
+ _out << _header1;
+ }
+ else
+ {
+ getHeaders(header, h1, h2);
+ _out << h1;
+ }
_out << title;
- _out << _header2;
+ if(header.empty())
+ {
+ _out << _header2;
+ }
+ else
+ {
+ _out << h2;
+ }
_out.inc();
_out.inc();
}
@@ -218,7 +199,6 @@ Slice::GeneratorBase::openDoc(const string& file, const string& title)
// is constructed from the Slice scoped name. Sub-directories are
// created as needed and the header is written to the file.
//
-
void
Slice::GeneratorBase::openDoc(const ContainedPtr& c)
{
@@ -248,7 +228,6 @@ Slice::GeneratorBase::openDoc(const ContainedPtr& c)
//
// Close an open HTML file after writing the footer.
//
-
void
Slice::GeneratorBase::closeDoc()
{
@@ -858,7 +837,16 @@ Slice::GeneratorBase::getLinkPath(const SyntaxTreeBasePtr& p, const ContainerPtr
// Find the first component where the two scopes differ.
//
bool commonEnclosingScope = false;
- StringList target = getContainer(p);
+ StringList target;
+ EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(p);
+ if(enumerator)
+ {
+ target = toStringList(enumerator->type());
+ }
+ else
+ {
+ target = getContainer(p);
+ }
StringList from = getContainer(c);
while(!target.empty() && !from.empty() && target.front() == from.front())
{
@@ -1144,6 +1132,57 @@ Slice::GeneratorBase::readFile(const string& file)
}
void
+Slice::GeneratorBase::getHeaders(const string& header, string& h1, string& h2)
+{
+ if(header.empty())
+ {
+ ostringstream hdr1;
+ XMLOutput O1(hdr1);
+ O1 << "<!-- Generated by Ice version " << ICE_STRING_VERSION << " -->";
+ O1 << sp;
+ O1 << nl << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">";
+ O1 << se("html");
+ O1 << se("head");
+ O1 << se("title") << nl;
+ h1 = hdr1.str();
+
+ // _header1 and _header2 store the bit preceding and following the title.
+ // _header1, the title text, and _header2 are written by openDoc().
+
+ ostringstream hdr2;
+ XMLOutput O2(hdr2);
+ O2.inc();
+ O2.inc();
+ O2 << nl << "</title>";
+ O2.dec();
+ O2 << nl << "</head>";
+ O2 << nl << "<body>";
+ h2 = hdr2.str();
+ }
+ else
+ {
+ readFile(header, h1, h2);
+ }
+}
+
+string
+Slice::GeneratorBase::getFooter(const string& footer)
+{
+ ostringstream ftr;
+ XMLOutput O(ftr);
+ if(footer.empty())
+ {
+ O << " </body>";
+ }
+ else
+ {
+ O << readFile(footer);
+ }
+ O << nl << "</html>";
+ return ftr.str();
+}
+
+void
Slice::GeneratorBase::readFile(const string& file, string& part1, string& part2)
{
ifstream in(file.c_str());
@@ -1185,18 +1224,18 @@ Slice::GeneratorBase::readFile(const string& file, string& part1, string& part2)
part2 = p2.str();
}
-Slice::IndexGenerator::IndexGenerator(const Files& files)
+Slice::StartPageGenerator::StartPageGenerator(const Files& files)
: GeneratorBase(_out, files)
{
- openDoc("index.html", "Slice Documentation Index");
+ openDoc("index.html", "Slice API Documentation");
}
-Slice::IndexGenerator::~IndexGenerator()
+Slice::StartPageGenerator::~StartPageGenerator()
{
::std::sort(_modules.begin(), _modules.end());
start("h1");
- _out << "Slice Documentation Index";
+ _out << "Slice API Documentation";
end();
start("h2");
_out << "Modules";
@@ -1217,91 +1256,228 @@ Slice::IndexGenerator::~IndexGenerator()
}
void
-Slice::IndexGenerator::generate(const ModulePtr& m)
+Slice::StartPageGenerator::generate(const ModulePtr& m)
{
string name = toString(m, 0, false);
string comment = getComment(m, 0, true);
_modules.push_back(make_pair(name, comment));
}
-Slice::TypesVisitor::TypesVisitor(Files& files)
+Slice::FileVisitor::FileVisitor(Files& files)
: _files(files)
{
}
bool
-Slice::TypesVisitor::visitUnitStart(const UnitPtr& u)
+Slice::FileVisitor::visitUnitStart(const UnitPtr& u)
{
return true;
}
bool
-Slice::TypesVisitor::visitModuleStart(const ModulePtr& m)
+Slice::FileVisitor::visitModuleStart(const ModulePtr& m)
{
_files.insert(m->definitionContext()->filename());
return true;
}
bool
-Slice::TypesVisitor::visitExceptionStart(const ExceptionPtr& e)
+Slice::FileVisitor::visitExceptionStart(const ExceptionPtr& e)
{
_files.insert(e->definitionContext()->filename());
return false;
}
bool
-Slice::TypesVisitor::visitClassDefStart(const ClassDefPtr& c)
+Slice::FileVisitor::visitClassDefStart(const ClassDefPtr& c)
{
_files.insert(c->definitionContext()->filename());
return false;
}
void
-Slice::TypesVisitor::visitClassDecl(const ClassDeclPtr& c)
+Slice::FileVisitor::visitClassDecl(const ClassDeclPtr& c)
{
_files.insert(c->definitionContext()->filename());
}
bool
-Slice::TypesVisitor::visitStructStart(const StructPtr& s)
+Slice::FileVisitor::visitStructStart(const StructPtr& s)
{
_files.insert(s->definitionContext()->filename());
return false;
}
void
-Slice::TypesVisitor::visitSequence(const SequencePtr& s)
+Slice::FileVisitor::visitSequence(const SequencePtr& s)
{
_files.insert(s->definitionContext()->filename());
}
void
-Slice::TypesVisitor::visitDictionary(const DictionaryPtr& d)
+Slice::FileVisitor::visitDictionary(const DictionaryPtr& d)
{
_files.insert(d->definitionContext()->filename());
}
void
-Slice::TypesVisitor::visitEnum(const EnumPtr& e)
+Slice::FileVisitor::visitEnum(const EnumPtr& e)
{
_files.insert(e->definitionContext()->filename());
}
-Slice::IndexVisitor::IndexVisitor(const Files& files)
- : _ig(files)
+Slice::StartPageVisitor::StartPageVisitor(const Files& files)
+ : _spg(files)
+{
+}
+
+bool
+Slice::StartPageVisitor::visitUnitStart(const UnitPtr& unit)
+{
+ return true;
+}
+
+bool
+Slice::StartPageVisitor::visitModuleStart(const ModulePtr& m)
+{
+ _spg.generate(m);
+ return false;
+}
+
+TOCGenerator::TOCGenerator(const Files& files, const string& header, const string& footer)
+ : GeneratorBase(_out, files)
+{
+ openDoc("toc.html", "Index", header, footer);
+ start("H1");
+ _out << "Index";
+ end();
+}
+
+TOCGenerator::~TOCGenerator()
+{
+ _modules.sort();
+ writeTOC();
+ closeDoc();
+}
+
+void
+TOCGenerator::generate(const ModulePtr& m)
+{
+ _modules.push_back(m);
+}
+
+void
+TOCGenerator::writeTOC()
+{
+ start("ul");
+ for(ModuleList::const_iterator i = _modules.begin(); i != _modules.end(); ++i)
+ {
+ writeEntry(*i);
+ }
+ end();
+}
+
+void
+TOCGenerator::writeEntry(const ContainedPtr& c)
+{
+ ContainedList cl;
+
+ ModulePtr m = ModulePtr::dynamicCast(c);
+ if(m)
+ {
+ cl = m->contents();
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(c);
+ if(en)
+ {
+ EnumeratorList enumerators = en->getEnumerators();
+ for(EnumeratorList::const_iterator i = enumerators.begin(); i != enumerators.end(); ++i)
+ {
+ cl.push_back(*i);
+ }
+ }
+
+ StructPtr s = StructPtr::dynamicCast(c);
+ if(s)
+ {
+ DataMemberList dml = s->dataMembers();
+ for(DataMemberList::const_iterator i = dml.begin(); i != dml.end(); ++i)
+ {
+ cl.push_back(*i);
+ }
+ }
+
+ ExceptionPtr e = ExceptionPtr::dynamicCast(c);
+ if(e)
+ {
+ DataMemberList dml = e->dataMembers();
+ for(DataMemberList::const_iterator i = dml.begin(); i != dml.end(); ++i)
+ {
+ cl.push_back(*i);
+ }
+ }
+
+ ClassDefPtr cdef = ClassDefPtr::dynamicCast(c);
+ if(!cdef)
+ {
+ ClassDeclPtr cdecl = ClassDeclPtr::dynamicCast(c);
+ if(cdecl)
+ {
+ cdef = cdecl->definition();
+ }
+ }
+
+ if(cdef)
+ {
+ DataMemberList dml = cdef->dataMembers();
+ for(DataMemberList::const_iterator i = dml.begin(); i != dml.end(); ++i)
+ {
+ cl.push_back(*i);
+ }
+ OperationList ol = cdef->operations();
+ for(OperationList::const_iterator j = ol.begin(); j != ol.end(); ++j)
+ {
+ cl.push_back(*j);
+ }
+ }
+
+ start("li");
+ if(!cl.empty())
+ {
+ cl.sort();
+ cl.unique();
+
+ _out << toString(c, 0, false, true);
+ start("ul");
+ for(ContainedList::const_iterator i = cl.begin(); i != cl.end(); ++i)
+ {
+ writeEntry(*i);
+ }
+ end();
+ }
+ else
+ {
+ _out << toString(c, 0, false, true);
+ }
+ end();
+}
+
+TOCVisitor::TOCVisitor(const Files& files, const string& header, const string& footer)
+ : _tg(files, header, footer)
{
}
bool
-Slice::IndexVisitor::visitUnitStart(const UnitPtr& unit)
+TOCVisitor::visitUnitStart(const UnitPtr&)
{
return true;
}
bool
-Slice::IndexVisitor::visitModuleStart(const ModulePtr& m)
+TOCVisitor::visitModuleStart(const ModulePtr& m)
{
- _ig.generate(m);
+ _tg.generate(m);
return false;
}
@@ -2106,19 +2282,19 @@ Slice::EnumGenerator::generate(const EnumPtr& e)
assert(_out.currIndent() == indent);
}
-Slice::Visitor::Visitor(const Files& files)
+Slice::PageVisitor::PageVisitor(const Files& files)
: _files(files)
{
}
bool
-Slice::Visitor::visitUnitStart(const UnitPtr& unit)
+Slice::PageVisitor::visitUnitStart(const UnitPtr& unit)
{
return true;
}
bool
-Slice::Visitor::visitModuleStart(const ModulePtr& m)
+Slice::PageVisitor::visitModuleStart(const ModulePtr& m)
{
XMLOutput O;
ModuleGenerator mg(O, _files);
@@ -2127,7 +2303,7 @@ Slice::Visitor::visitModuleStart(const ModulePtr& m)
}
bool
-Slice::Visitor::visitExceptionStart(const ExceptionPtr& e)
+Slice::PageVisitor::visitExceptionStart(const ExceptionPtr& e)
{
XMLOutput O;
ExceptionGenerator eg(O, _files);
@@ -2136,7 +2312,7 @@ Slice::Visitor::visitExceptionStart(const ExceptionPtr& e)
}
bool
-Slice::Visitor::visitClassDefStart(const ClassDefPtr& c)
+Slice::PageVisitor::visitClassDefStart(const ClassDefPtr& c)
{
XMLOutput O;
ClassGenerator cg(O, _files);
@@ -2145,7 +2321,7 @@ Slice::Visitor::visitClassDefStart(const ClassDefPtr& c)
}
bool
-Slice::Visitor::visitStructStart(const StructPtr& s)
+Slice::PageVisitor::visitStructStart(const StructPtr& s)
{
XMLOutput O;
StructGenerator sg(O, _files);
@@ -2154,7 +2330,7 @@ Slice::Visitor::visitStructStart(const StructPtr& s)
}
void
-Slice::Visitor::visitEnum(const EnumPtr& e)
+Slice::PageVisitor::visitEnum(const EnumPtr& e)
{
XMLOutput O;
EnumGenerator eg(O, _files);