1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmDocumentationFormatterHTML.cxx,v $
6 Date: $Date: 2008-10-10 15:23:35 $
7 Version: $Revision: 1.14 $
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"
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.
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
))
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
))
89 // Print the hyperlink itself.
91 for(const char* c
= begin
; c
!= end
; ++c
)
93 cmDocumentationPrintHTMLChar(os
, *c
);
97 // The name of the hyperlink is the text itself.
98 for(const char* c
= begin
; c
!= end
; ++c
)
100 cmDocumentationPrintHTMLChar(os
, *c
);
104 // Return the position at which to continue scanning the input
110 cmDocumentationFormatterHTML::cmDocumentationFormatterHTML()
111 :cmDocumentationFormatter()
115 void cmDocumentationFormatterHTML
116 ::PrintSection(std::ostream
& os
,
117 const cmDocumentationSection
§ion
,
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
)
133 os
<< "<h2><a name=\"section_" << name
<< "\"/>" << name
<< "</h2>\n";
137 for(std::vector
<cmDocumentationEntry
>::const_iterator op
138 = entries
.begin(); op
!= entries
.end(); ++ op
)
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>";
152 for(std::vector
<cmDocumentationEntry
>::const_iterator op
= entries
.begin();
153 op
!= entries
.end();)
158 for(;op
!= entries
.end() && op
->Name
.size(); ++op
)
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());
173 this->PrintFormatted(os
, op
->Full
.c_str());
182 this->PrintFormatted(os
, op
->Brief
.c_str());
189 void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream
& os
,
193 this->PrintHTMLEscapes(os
, text
);
197 void cmDocumentationFormatterHTML::PrintParagraph(std::ostream
& os
,
201 this->PrintHTMLEscapes(os
, text
);
204 //----------------------------------------------------------------------------
205 void cmDocumentationFormatterHTML::PrintHeader(const char* docname
,
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
,
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.
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"))
261 os
<< "<h2><a name=\"section_Index\"/>Master Index</h2>\n";
263 for(unsigned int i
=0; i
< sections
.size(); ++i
)
265 std::string name
= sections
[i
]->
266 GetName((this->GetForm()));
267 os
<< " <li><a href=\"#section_"
268 << name
<< "\"<b>" << name
<< "</b></a></li>\n";