cmDocumentationFormatterHTML.cxx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmDocumentationFormatterHTML.h"
  14. #include "cmDocumentationSection.h"
  15. //----------------------------------------------------------------------------
  16. static bool cmDocumentationIsHyperlinkChar(char c)
  17. {
  18. // This is not a complete list but works for CMake documentation.
  19. return ((c >= 'A' && c <= 'Z') ||
  20. (c >= 'a' && c <= 'z') ||
  21. (c >= '0' && c <= '9') ||
  22. c == '-' || c == '.' || c == '/' || c == '~' || c == '@' ||
  23. c == ':' || c == '_' || c == '&' || c == '?' || c == '=');
  24. }
  25. //----------------------------------------------------------------------------
  26. static void cmDocumentationPrintHTMLChar(std::ostream& os, char c)
  27. {
  28. // Use an escape sequence if necessary.
  29. static std::map<char,std::string> escapes;
  30. if (escapes.empty())
  31. {
  32. escapes['<'] = "&lt;";
  33. escapes['>'] = "&gt;";
  34. escapes['&'] = "&amp;";
  35. escapes['\n'] = "<br>";
  36. }
  37. if (escapes.find(c) == escapes.end())
  38. {
  39. // No escape sequence is needed.
  40. os << c;
  41. return;
  42. }
  43. os << escapes[c];
  44. return;
  45. }
  46. //----------------------------------------------------------------------------
  47. const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin)
  48. {
  49. // Look for the end of the link.
  50. const char* end = begin;
  51. while(cmDocumentationIsHyperlinkChar(*end))
  52. {
  53. ++end;
  54. }
  55. // Print the hyperlink itself.
  56. os << "<a href=\"";
  57. for(const char* c = begin; c != end; ++c)
  58. {
  59. cmDocumentationPrintHTMLChar(os, *c);
  60. }
  61. os << "\">";
  62. // The name of the hyperlink is the text itself.
  63. for(const char* c = begin; c != end; ++c)
  64. {
  65. cmDocumentationPrintHTMLChar(os, *c);
  66. }
  67. os << "</a>";
  68. // Return the position at which to continue scanning the input
  69. // string.
  70. return end;
  71. }
  72. cmDocumentationFormatterHTML::cmDocumentationFormatterHTML()
  73. :cmDocumentationFormatter()
  74. {
  75. }
  76. void cmDocumentationFormatterHTML
  77. ::PrintSection(std::ostream& os,
  78. const cmDocumentationSection &section,
  79. const char* name)
  80. {
  81. if(name)
  82. {
  83. os << "<h2><a name=\"section_" << name << "\"/>" << name << "</h2>\n";
  84. }
  85. const std::vector<cmDocumentationEntry> &entries =
  86. section.GetEntries();
  87. os << "<ul>\n";
  88. for(std::vector<cmDocumentationEntry>::const_iterator op
  89. = entries.begin(); op != entries.end(); ++ op )
  90. {
  91. if(op->Name.size())
  92. {
  93. os << " <li><a href=\"#command_"
  94. << op->Name.c_str() << "\"><b><code>";
  95. this->PrintHTMLEscapes(os, op->Name.c_str());
  96. os << "</code></b></a></li>";
  97. }
  98. }
  99. os << "</ul>\n" ;
  100. for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
  101. op != entries.end();)
  102. {
  103. if(op->Name.size())
  104. {
  105. os << "<ul>\n";
  106. for(;op != entries.end() && op->Name.size(); ++op)
  107. {
  108. os << " <li>\n";
  109. if(op->Name.size())
  110. {
  111. os << " <a name=\"command_"<<
  112. op->Name.c_str() << "\"><b><code>";
  113. this->PrintHTMLEscapes(os, op->Name.c_str());
  114. os << "</code></b></a>: ";
  115. }
  116. this->PrintHTMLEscapes(os, op->Brief.c_str());
  117. if(op->Full.size())
  118. {
  119. os << "<br>\n ";
  120. this->PrintFormatted(os, op->Full.c_str());
  121. }
  122. os << "\n";
  123. os << " </li>\n";
  124. }
  125. os << "</ul>\n";
  126. }
  127. else
  128. {
  129. this->PrintFormatted(os, op->Brief.c_str());
  130. os << "\n";
  131. ++op;
  132. }
  133. }
  134. }
  135. void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os,
  136. const char* text)
  137. {
  138. os << "<pre>";
  139. this->PrintHTMLEscapes(os, text);
  140. os << "</pre>\n ";
  141. }
  142. void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os,
  143. const char* text)
  144. {
  145. os << "<p>";
  146. this->PrintHTMLEscapes(os, text);
  147. }
  148. //----------------------------------------------------------------------------
  149. void cmDocumentationFormatterHTML::PrintHeader(const char* /*name*/,
  150. std::ostream& os)
  151. {
  152. os << "<html><body>\n";
  153. }
  154. //----------------------------------------------------------------------------
  155. void cmDocumentationFormatterHTML::PrintFooter(std::ostream& os)
  156. {
  157. os << "</body></html>\n";
  158. }
  159. //----------------------------------------------------------------------------
  160. void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os,
  161. const char* text)
  162. {
  163. // Hyperlink prefixes.
  164. static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0};
  165. // Print each character.
  166. for(const char* p = text; *p;)
  167. {
  168. // Handle hyperlinks specially to make them active.
  169. bool found_hyperlink = false;
  170. for(const char** h = hyperlinks; !found_hyperlink && *h; ++h)
  171. {
  172. if(strncmp(p, *h, strlen(*h)) == 0)
  173. {
  174. p = cmDocumentationPrintHTMLLink(os, p);
  175. found_hyperlink = true;
  176. }
  177. }
  178. // Print other characters normally.
  179. if(!found_hyperlink)
  180. {
  181. cmDocumentationPrintHTMLChar(os, *p++);
  182. }
  183. }
  184. }