/*============================================================================ CMake - Cross Platform Makefile Generator Copyright 2000-2009 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ #include "cmDocumentationFormatterHTML.h" #include "cmDocumentationSection.h" #include "cmVersion.h" //---------------------------------------------------------------------------- static bool cmDocumentationIsHyperlinkChar(char c) { // This is not a complete list but works for CMake documentation. return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '.' || c == '/' || c == '~' || c == '@' || c == ':' || c == '_' || c == '&' || c == '?' || c == '='); } //---------------------------------------------------------------------------- static void cmDocumentationPrintHTMLChar(std::ostream& os, char c) { // Use an escape sequence if necessary. switch (c) { case '<': os << "<"; break; case '>': os << ">"; break; case '&': os << "&"; break; case '\n': os << "
"; break; default: os << c; } } //---------------------------------------------------------------------------- bool cmDocumentationHTMLIsIdChar(char c) { // From the HTML specification: // ID and NAME tokens must begin with a letter ([A-Za-z]) and may // be followed by any number of letters, digits ([0-9]), hyphens // ("-"), underscores ("_"), colons (":"), and periods ("."). return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == ':' || c == '.'); } //---------------------------------------------------------------------------- void cmDocumentationPrintHTMLId(std::ostream& os, const char* begin) { for(const char* c = begin; *c; ++c) { if(cmDocumentationHTMLIsIdChar(*c)) { os << *c; } } } //---------------------------------------------------------------------------- const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin) { // Look for the end of the link. const char* end = begin; while(cmDocumentationIsHyperlinkChar(*end)) { ++end; } // Print the hyperlink itself. os << ""; // The name of the hyperlink is the text itself. for(const char* c = begin; c != end; ++c) { cmDocumentationPrintHTMLChar(os, *c); } os << ""; // Return the position at which to continue scanning the input // string. return end; } cmDocumentationFormatterHTML::cmDocumentationFormatterHTML() :cmDocumentationFormatter() { } void cmDocumentationFormatterHTML ::PrintSection(std::ostream& os, const cmDocumentationSection §ion, const char* name) { std::string prefix = this->ComputeSectionLinkPrefix(name); const std::vector &entries = section.GetEntries(); // skip the index if the help for only a single item (--help-command, // --help-policy, --help-property, --help-module) is printed bool isSingleItemHelp = ((name!=0) && (strcmp(name, "SingleItem")==0)); if (!isSingleItemHelp) { if (name) { os << "

" << name << "

\n"; } // Is a list needed? for(std::vector::const_iterator op = entries.begin(); op != entries.end(); ++ op ) { if (op->Name.size()) { os << "\n" ; break; // Skip outer loop termination test } } } for(std::vector::const_iterator op = entries.begin(); op != entries.end();) { if(op->Name.size()) { os << "
    \n"; for(;op != entries.end() && op->Name.size(); ++op) { os << "
  • \n"; if(op->Name.size()) { os << " Name.c_str()); os << "\">"; this->PrintHTMLEscapes(os, op->Name.c_str()); os << ": "; } this->PrintHTMLEscapes(os, op->Brief.c_str()); if(op->Full.size()) { os << "
    \n "; this->PrintFormatted(os, op->Full.c_str()); } os << "\n"; os << "
  • \n"; } os << "
\n"; } else { this->PrintFormatted(os, op->Brief.c_str()); os << "\n"; ++op; } } } void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os, const char* text) { os << "
";
  this->PrintHTMLEscapes(os, text);
  os << "
\n "; } void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os, const char* text) { os << "

"; this->PrintHTMLEscapes(os, text); os << "

\n"; } //---------------------------------------------------------------------------- void cmDocumentationFormatterHTML::PrintHeader(const char* docname, const char* appname, std::ostream& os) { os << "\n"; os << "\n"; os << ""; os << docname << " - " << appname; os << "\n"; } //---------------------------------------------------------------------------- void cmDocumentationFormatterHTML::PrintFooter(std::ostream& os) { os << "\n"; } //---------------------------------------------------------------------------- void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os, const char* text) { // Hyperlink prefixes. static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0}; // Print each character. for(const char* p = text; *p;) { // Handle hyperlinks specially to make them active. bool found_hyperlink = false; for(const char** h = hyperlinks; !found_hyperlink && *h; ++h) { if(strncmp(p, *h, strlen(*h)) == 0) { p = cmDocumentationPrintHTMLLink(os, p); found_hyperlink = true; } } // Print other characters normally. if(!found_hyperlink) { cmDocumentationPrintHTMLChar(os, *p++); } } } void cmDocumentationFormatterHTML ::PrintIndex(std::ostream& os, std::vector& sections) { // skip the index if only the help for a single item is printed if ((sections.size() == 1) && (sections[0]->GetName(this->GetForm()) != 0 ) && (std::string(sections[0]->GetName(this->GetForm())) == "SingleItem")) { return; } os << "

Master Index " << "CMake " << cmVersion::GetCMakeVersion() << "

\n"; if (!sections.empty()) { os << "
    \n"; for(unsigned int i=0; i < sections.size(); ++i) { std::string name = sections[i]->GetName((this->GetForm())); os << "
  • " << name << "
  • \n"; } os << "
\n"; } }