You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
5.6 KiB

  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. std::map<char,std::string> escapes;
  30. escapes['<'] = "&lt;";
  31. escapes['>'] = "&gt;";
  32. escapes['&'] = "&amp;";
  33. escapes['\n'] = "<br>";
  34. if (escapes.find(c) == escapes.end())
  35. {
  36. // No escape sequence is needed.
  37. os << c;
  38. return;
  39. }
  40. os << escapes[c];
  41. return;
  42. }
  43. //----------------------------------------------------------------------------
  44. const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin)
  45. {
  46. // Look for the end of the link.
  47. const char* end = begin;
  48. while(cmDocumentationIsHyperlinkChar(*end))
  49. {
  50. ++end;
  51. }
  52. // Print the hyperlink itself.
  53. os << "<a href=\"";
  54. for(const char* c = begin; c != end; ++c)
  55. {
  56. cmDocumentationPrintHTMLChar(os, *c);
  57. }
  58. os << "\">";
  59. // The name of the hyperlink is the text itself.
  60. for(const char* c = begin; c != end; ++c)
  61. {
  62. cmDocumentationPrintHTMLChar(os, *c);
  63. }
  64. os << "</a>";
  65. // Return the position at which to continue scanning the input
  66. // string.
  67. return end;
  68. }
  69. cmDocumentationFormatterHTML::cmDocumentationFormatterHTML()
  70. :cmDocumentationFormatter()
  71. {
  72. }
  73. void cmDocumentationFormatterHTML
  74. ::PrintSection(std::ostream& os,
  75. const cmDocumentationSection &section,
  76. const char* name)
  77. {
  78. if(name)
  79. {
  80. os << "<h2>" << name << "</h2>\n";
  81. }
  82. const std::vector<cmDocumentationEntry> &entries =
  83. section.GetEntries();
  84. os << "<ul>\n";
  85. for(std::vector<cmDocumentationEntry>::const_iterator op
  86. = entries.begin(); op != entries.end(); ++ op )
  87. {
  88. if(op->Name.size())
  89. {
  90. os << " <li><a href=\"#command_"
  91. << op->Name.c_str() << "\"><b><code>";
  92. this->PrintHTMLEscapes(os, op->Name.c_str());
  93. os << "</code></b></a></li>";
  94. }
  95. }
  96. os << "</ul>\n" ;
  97. for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
  98. op != entries.end();)
  99. {
  100. if(op->Name.size())
  101. {
  102. os << "<ul>\n";
  103. for(;op != entries.end() && op->Name.size(); ++op)
  104. {
  105. os << " <li>\n";
  106. if(op->Name.size())
  107. {
  108. os << " <a name=\"command_"<<
  109. op->Name.c_str() << "\"><b><code>";
  110. this->PrintHTMLEscapes(os, op->Name.c_str());
  111. os << "</code></b></a>: ";
  112. }
  113. this->PrintHTMLEscapes(os, op->Brief.c_str());
  114. if(op->Full.size())
  115. {
  116. os << "<br>\n ";
  117. this->PrintFormatted(os, op->Full.c_str());
  118. }
  119. os << "\n";
  120. os << " </li>\n";
  121. }
  122. os << "</ul>\n";
  123. }
  124. else
  125. {
  126. this->PrintFormatted(os, op->Brief.c_str());
  127. os << "\n";
  128. ++op;
  129. }
  130. }
  131. }
  132. void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os,
  133. const char* text)
  134. {
  135. os << "<pre>";
  136. this->PrintHTMLEscapes(os, text);
  137. os << "</pre>\n ";
  138. }
  139. void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os,
  140. const char* text)
  141. {
  142. os << "<p>";
  143. this->PrintHTMLEscapes(os, text);
  144. }
  145. //----------------------------------------------------------------------------
  146. void cmDocumentationFormatterHTML::PrintHeader(const char* /*name*/,
  147. std::ostream& os)
  148. {
  149. os << "<html><body>\n";
  150. }
  151. //----------------------------------------------------------------------------
  152. void cmDocumentationFormatterHTML::PrintFooter(std::ostream& os)
  153. {
  154. os << "</body></html>\n";
  155. }
  156. //----------------------------------------------------------------------------
  157. void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os,
  158. const char* text)
  159. {
  160. // Hyperlink prefixes.
  161. static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0};
  162. // Print each character.
  163. for(const char* p = text; *p;)
  164. {
  165. // Handle hyperlinks specially to make them active.
  166. bool found_hyperlink = false;
  167. for(const char** h = hyperlinks; !found_hyperlink && *h; ++h)
  168. {
  169. if(strncmp(p, *h, strlen(*h)) == 0)
  170. {
  171. p = cmDocumentationPrintHTMLLink(os, p);
  172. found_hyperlink = true;
  173. }
  174. }
  175. // Print other characters normally.
  176. if(!found_hyperlink)
  177. {
  178. cmDocumentationPrintHTMLChar(os, *p++);
  179. }
  180. }
  181. }