diff options
author | Alexander Neundorf <neundorf@kde.org> | 2008-02-19 19:33:43 (GMT) |
---|---|---|
committer | Alexander Neundorf <neundorf@kde.org> | 2008-02-19 19:33:43 (GMT) |
commit | 969ea3f4491a8c3408bf59744545674b3a647657 (patch) | |
tree | 69b48e1c71c000d6723f9047427b69e7c92ee916 /Source/cmDocumentationFormatterDocbook.cxx | |
parent | ee2a13b11f08efcde4ec3579763ae3236b278693 (diff) | |
download | CMake-969ea3f4491a8c3408bf59744545674b3a647657.zip CMake-969ea3f4491a8c3408bf59744545674b3a647657.tar.gz CMake-969ea3f4491a8c3408bf59744545674b3a647657.tar.bz2 |
ENH: add support for creating the documentation in docbook format
(http://www.oasis-open.org/docbook/xml/4.2/), which users can then convert
to other formats.
Tested with meinproc from KDE, which generates HTML pages which look good.
Alex
Diffstat (limited to 'Source/cmDocumentationFormatterDocbook.cxx')
-rw-r--r-- | Source/cmDocumentationFormatterDocbook.cxx | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/Source/cmDocumentationFormatterDocbook.cxx b/Source/cmDocumentationFormatterDocbook.cxx new file mode 100644 index 0000000..65f4bf8 --- /dev/null +++ b/Source/cmDocumentationFormatterDocbook.cxx @@ -0,0 +1,254 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + 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 << "<ulink url=\""; + for(const char* c = begin; c != end; ++c) + { + cmDocumentationPrintDocbookChar(os, *c); + } + 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 << "<sect1 id=\"section_" << name << "\">\n" + "<title>\n" << name << "</title>\n"; + } + else + { + static unsigned int i=0; + i++; + os << "<sect1 id=\"section_" << name << i << "\">\n" + "<title>\n" << name << "</title>\n"; + } + } + + const std::vector<cmDocumentationEntry> &entries = + section.GetEntries(); + + os << "<itemizedlist>\n"; + for(std::vector<cmDocumentationEntry>::const_iterator op + = entries.begin(); op != entries.end(); ++ op ) + { + if(op->Name.size()) + { + os << " <listitem><link linkend=\"command_"; + cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); + os << "\"><emphasis><literal>"; + cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); + os << "</literal></emphasis></link></listitem>"; + } + } + os << "</itemizedlist>\n" ; + + for(std::vector<cmDocumentationEntry>::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 << " <para id=\"command_"; + cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); + + // make sure that each id exists only once, e.g. + // command_COMPILE_DEFINITIONS exists at least twice. 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 = "command_"; + 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 << "\"><sect2><title>"; + cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); + os << "</title></sect2> "; + } + cmDocumentationPrintDocbookEscapes(os, op->Brief.c_str()); + if(op->Name.size()) + { + os << "</para>\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 << "</sect1>\n"; + } +} + +void cmDocumentationFormatterDocbook::PrintPreformatted(std::ostream& os, + const char* text) +{ + os << "<literallayout>"; + cmDocumentationPrintDocbookEscapes(os, text); + os << "</literallayout>\n "; +} + +void cmDocumentationFormatterDocbook::PrintParagraph(std::ostream& os, + const char* text) +{ + os << "<para>"; + cmDocumentationPrintDocbookEscapes(os, text); + os << "</para>"; +} + +//---------------------------------------------------------------------------- +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 << "<?xml version=\"1.0\" ?>\n" + "<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\" " + "\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\" [\n" + "<!ENTITY % addindex \"IGNORE\">\n" + "<!ENTITY % English \"INCLUDE\"> ]>\n" + "<article>\n" + "<articleinfo>\n" + "<title>" << name << "</title>\n" + "</articleinfo>\n"; +} + +//---------------------------------------------------------------------------- +void cmDocumentationFormatterDocbook::PrintFooter(std::ostream& os) +{ + os << "</article>\n"; +} + |