Fix Xcode project references to the source tree
[cmake.git] / Source / cmDocumentationFormatterHTML.cxx
blob343bac57dd6d09924b85c84160ccea9cbd3fdbe8
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmDocumentationFormatterHTML.cxx,v $
5 Language: C++
6 Date: $Date: 2009-09-15 00:54:22 $
7 Version: $Revision: 1.15 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmDocumentationFormatterHTML.h"
18 #include "cmDocumentationSection.h"
19 #include "cmVersion.h"
20 //----------------------------------------------------------------------------
21 static bool cmDocumentationIsHyperlinkChar(char c)
23 // This is not a complete list but works for CMake documentation.
24 return ((c >= 'A' && c <= 'Z') ||
25 (c >= 'a' && c <= 'z') ||
26 (c >= '0' && c <= '9') ||
27 c == '-' || c == '.' || c == '/' || c == '~' || c == '@' ||
28 c == ':' || c == '_' || c == '&' || c == '?' || c == '=');
31 //----------------------------------------------------------------------------
32 static void cmDocumentationPrintHTMLChar(std::ostream& os, char c)
34 // Use an escape sequence if necessary.
35 switch (c)
37 case '<':
38 os << "&lt;";
39 break;
40 case '>':
41 os << "&gt;";
42 break;
43 case '&':
44 os << "&amp;";
45 break;
46 case '\n':
47 os << "<br>";
48 break;
49 default:
50 os << c;
54 //----------------------------------------------------------------------------
55 bool cmDocumentationHTMLIsIdChar(char c)
57 // From the HTML specification:
58 // ID and NAME tokens must begin with a letter ([A-Za-z]) and may
59 // be followed by any number of letters, digits ([0-9]), hyphens
60 // ("-"), underscores ("_"), colons (":"), and periods (".").
61 return ((c >= 'A' && c <= 'Z') ||
62 (c >= 'a' && c <= 'z') ||
63 (c >= '0' && c <= '9') ||
64 c == '-' || c == '_' || c == ':' || c == '.');
67 //----------------------------------------------------------------------------
68 void cmDocumentationPrintHTMLId(std::ostream& os, const char* begin)
70 for(const char* c = begin; *c; ++c)
72 if(cmDocumentationHTMLIsIdChar(*c))
74 os << *c;
79 //----------------------------------------------------------------------------
80 const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin)
82 // Look for the end of the link.
83 const char* end = begin;
84 while(cmDocumentationIsHyperlinkChar(*end))
86 ++end;
89 // Print the hyperlink itself.
90 os << "<a href=\"";
91 for(const char* c = begin; c != end; ++c)
93 cmDocumentationPrintHTMLChar(os, *c);
95 os << "\">";
97 // The name of the hyperlink is the text itself.
98 for(const char* c = begin; c != end; ++c)
100 cmDocumentationPrintHTMLChar(os, *c);
102 os << "</a>";
104 // Return the position at which to continue scanning the input
105 // string.
106 return end;
110 cmDocumentationFormatterHTML::cmDocumentationFormatterHTML()
111 :cmDocumentationFormatter()
115 void cmDocumentationFormatterHTML
116 ::PrintSection(std::ostream& os,
117 const cmDocumentationSection &section,
118 const char* name)
120 std::string prefix = this->ComputeSectionLinkPrefix(name);
122 const std::vector<cmDocumentationEntry> &entries =
123 section.GetEntries();
125 // skip the index if the help for only a single item (--help-command,
126 // --help-policy, --help-property, --help-module) is printed
127 bool isSingleItemHelp = ((name!=0) && (strcmp(name, "SingleItem")==0));
129 if (!isSingleItemHelp)
131 if (name)
133 os << "<h2><a name=\"section_" << name << "\"/>" << name << "</h2>\n";
136 os << "<ul>\n";
137 for(std::vector<cmDocumentationEntry>::const_iterator op
138 = entries.begin(); op != entries.end(); ++ op )
140 if(op->Name.size())
142 os << " <li><a href=\"#" << prefix << ":";
143 cmDocumentationPrintHTMLId(os, op->Name.c_str());
144 os << "\"><b><code>";
145 this->PrintHTMLEscapes(os, op->Name.c_str());
146 os << "</code></b></a></li>";
149 os << "</ul>\n" ;
152 for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
153 op != entries.end();)
155 if(op->Name.size())
157 os << "<ul>\n";
158 for(;op != entries.end() && op->Name.size(); ++op)
160 os << " <li>\n";
161 if(op->Name.size())
163 os << " <a name=\"" << prefix << ":";
164 cmDocumentationPrintHTMLId(os, op->Name.c_str());
165 os << "\"><b><code>";
166 this->PrintHTMLEscapes(os, op->Name.c_str());
167 os << "</code></b></a>: ";
169 this->PrintHTMLEscapes(os, op->Brief.c_str());
170 if(op->Full.size())
172 os << "<br>\n ";
173 this->PrintFormatted(os, op->Full.c_str());
175 os << "\n";
176 os << " </li>\n";
178 os << "</ul>\n";
180 else
182 this->PrintFormatted(os, op->Brief.c_str());
183 os << "\n";
184 ++op;
189 void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os,
190 const char* text)
192 os << "<pre>";
193 this->PrintHTMLEscapes(os, text);
194 os << "</pre>\n ";
197 void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os,
198 const char* text)
200 os << "<p>";
201 this->PrintHTMLEscapes(os, text);
204 //----------------------------------------------------------------------------
205 void cmDocumentationFormatterHTML::PrintHeader(const char* docname,
206 const char* appname,
207 std::ostream& os)
209 os << "<html><head><title>";
210 os << docname << " - " << appname;
211 os << "</title></head><body>\n";
214 //----------------------------------------------------------------------------
215 void cmDocumentationFormatterHTML::PrintFooter(std::ostream& os)
217 os << "</body></html>\n";
220 //----------------------------------------------------------------------------
221 void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os,
222 const char* text)
224 // Hyperlink prefixes.
225 static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0};
227 // Print each character.
228 for(const char* p = text; *p;)
230 // Handle hyperlinks specially to make them active.
231 bool found_hyperlink = false;
232 for(const char** h = hyperlinks; !found_hyperlink && *h; ++h)
234 if(strncmp(p, *h, strlen(*h)) == 0)
236 p = cmDocumentationPrintHTMLLink(os, p);
237 found_hyperlink = true;
241 // Print other characters normally.
242 if(!found_hyperlink)
244 cmDocumentationPrintHTMLChar(os, *p++);
249 void cmDocumentationFormatterHTML
250 ::PrintIndex(std::ostream& os,
251 std::vector<const cmDocumentationSection *>& sections)
253 // skip the index if only the help for a single item is printed
254 if ((sections.size() == 1)
255 && (sections[0]->GetName(this->GetForm()) != 0 )
256 && (std::string(sections[0]->GetName(this->GetForm())) == "SingleItem"))
258 return;
261 os << "<h2><a name=\"section_Index\"/>Master Index "
262 << "CMake " << cmVersion::GetCMakeVersion()
263 << "</h2>\n";
264 os << "<ul>\n";
265 for(unsigned int i=0; i < sections.size(); ++i)
267 std::string name = sections[i]->
268 GetName((this->GetForm()));
269 os << " <li><a href=\"#section_"
270 << name << "\"<b>" << name << "</b></a></li>\n";
272 os << "</ul>\n";