/*========================================================================= Program: CMake - Cross-Platform Makefile Generator Module: $RCSfile: cmDocumentationFormatterDocbook.cxx,v $ Language: C++ Date: $Date: 2008-05-05 17:38:19 $ Version: $Revision: 1.1.2.1 $ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "cmDocumentationFormatterDocbook.h" #include "cmDocumentationSection.h" //---------------------------------------------------------------------------- // this function is a copy of the one in the HTML formatter // the three functions below are slightly modified copies static bool cmDocumentationIsHyperlinkCharDocbook(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 cmDocumentationPrintDocbookChar(std::ostream& os, char c) { // Use an escape sequence if necessary. switch(c) { case '<': os << "<"; break; case '>': os << ">"; break; case '&': os << "&"; break; default: os << c; } } //---------------------------------------------------------------------------- const char* cmDocumentationPrintDocbookLink(std::ostream& os,const char* begin) { // Look for the end of the link. const char* end = begin; while(cmDocumentationIsHyperlinkCharDocbook(*end)) { ++end; } // Print the hyperlink itself. os << ""; return end; } //---------------------------------------------------------------------------- void cmDocumentationPrintDocbookEscapes(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 = cmDocumentationPrintDocbookLink(os, p); found_hyperlink = true; } } // Print other characters normally. if(!found_hyperlink) { cmDocumentationPrintDocbookChar(os, *p++); } } } cmDocumentationFormatterDocbook::cmDocumentationFormatterDocbook() :cmDocumentationFormatter() { } void cmDocumentationFormatterDocbook ::PrintSection(std::ostream& os, const cmDocumentationSection §ion, const char* name) { if(name) { std::string id = "section_"; id += name; if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end()) { this->EmittedLinkIds.insert(id); os << "\n" "\n" << name << "\n"; } else { static unsigned int i=0; i++; os << "\n" "\n" << name << "\n"; } } std::string prefix = this->ComputeSectionLinkPrefix(name); const std::vector &entries = section.GetEntries(); os << "\n"; for(std::vector::const_iterator op = entries.begin(); op != entries.end(); ++ op ) { if(op->Name.size()) { os << " Name.c_str()); os << "\">"; cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); os << ""; } } os << "\n" ; for(std::vector::const_iterator op = entries.begin(); op != entries.end();) { if(op->Name.size()) { for(;op != entries.end() && op->Name.size(); ++op) { if(op->Name.size()) { os << " Name.c_str()); // make sure that each id exists only once. Since it seems // not easily possible to determine which link refers to which id, // we have at least to make sure that the duplicated id's get a // different name (by appending an increasing number), Alex std::string id = prefix; id += "_"; id += op->Name; if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end()) { this->EmittedLinkIds.insert(id); } else { static unsigned int i=0; i++; os << i; } // continue as normal... os << "\">"; cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); os << " "; } cmDocumentationPrintDocbookEscapes(os, op->Brief.c_str()); if(op->Name.size()) { os << "\n"; } if(op->Full.size()) { // a line break seems to be simply a line break with docbook os << "\n "; this->PrintFormatted(os, op->Full.c_str()); } os << "\n"; } } else { this->PrintFormatted(os, op->Brief.c_str()); os << "\n"; ++op; } } if(name) { os << "\n"; } } void cmDocumentationFormatterDocbook::PrintPreformatted(std::ostream& os, const char* text) { os << ""; cmDocumentationPrintDocbookEscapes(os, text); os << "\n "; } void cmDocumentationFormatterDocbook::PrintParagraph(std::ostream& os, const char* text) { os << ""; cmDocumentationPrintDocbookEscapes(os, text); os << ""; } //---------------------------------------------------------------------------- void cmDocumentationFormatterDocbook::PrintHeader(const char* name, std::ostream& os) { // this one is used to ensure that we don't create multiple link targets // with the same name. We can clear it here since we are at the // start of a document here. this->EmittedLinkIds.clear(); os << "\n" "\n" " ]>\n" "
\n" "\n" "" << name << "\n" "\n"; } //---------------------------------------------------------------------------- void cmDocumentationFormatterDocbook::PrintFooter(std::ostream& os) { os << "
\n"; }