|
|
@@ -969,8 +969,20 @@ void cmDocumentation::PrintColumn(std::ostream& os, const char* text)
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-void cmDocumentation::PrintHTMLEscapes(std::ostream& os, const char* text)
|
|
|
+static bool cmDocumentationIsHyperlinkChar(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 cmDocumentationPrintHTMLChar(std::ostream& os, char c)
|
|
|
{
|
|
|
+ // Use an escape sequence if necessary.
|
|
|
static cmDocumentationEntry escapes[] =
|
|
|
{
|
|
|
{"<", "<", 0},
|
|
|
@@ -979,20 +991,73 @@ void cmDocumentation::PrintHTMLEscapes(std::ostream& os, const char* text)
|
|
|
{"\n", "<br>", 0},
|
|
|
{0,0,0}
|
|
|
};
|
|
|
- for(const char* p = text; *p; ++p)
|
|
|
+ for(const cmDocumentationEntry* op = escapes; op->name; ++op)
|
|
|
+ {
|
|
|
+ if(op->name[0] == c)
|
|
|
+ {
|
|
|
+ os << op->brief;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // No escape sequence is needed.
|
|
|
+ os << c;
|
|
|
+}
|
|
|
+
|
|
|
+//----------------------------------------------------------------------------
|
|
|
+const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin)
|
|
|
+{
|
|
|
+ // Look for the end of the link.
|
|
|
+ const char* end = begin;
|
|
|
+ while(cmDocumentationIsHyperlinkChar(*end))
|
|
|
+ {
|
|
|
+ ++end;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Print the hyperlink itself.
|
|
|
+ os << "<a href=\"";
|
|
|
+ for(const char* c = begin; c != end; ++c)
|
|
|
+ {
|
|
|
+ cmDocumentationPrintHTMLChar(os, *c);
|
|
|
+ }
|
|
|
+ os << "\">";
|
|
|
+
|
|
|
+ // The name of the hyperlink is the text itself.
|
|
|
+ for(const char* c = begin; c != end; ++c)
|
|
|
{
|
|
|
- bool found = false;
|
|
|
- for(const cmDocumentationEntry* op = escapes; !found && op->name; ++op)
|
|
|
+ cmDocumentationPrintHTMLChar(os, *c);
|
|
|
+ }
|
|
|
+ os << "</a>";
|
|
|
+
|
|
|
+ // Return the position at which to continue scanning the input
|
|
|
+ // string.
|
|
|
+ return end;
|
|
|
+}
|
|
|
+
|
|
|
+//----------------------------------------------------------------------------
|
|
|
+void cmDocumentation::PrintHTMLEscapes(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(op->name[0] == *p)
|
|
|
+ if(strncmp(p, *h, strlen(*h)) == 0)
|
|
|
{
|
|
|
- os << op->brief;
|
|
|
- found = true;
|
|
|
+ p = cmDocumentationPrintHTMLLink(os, p);
|
|
|
+ found_hyperlink = true;
|
|
|
}
|
|
|
}
|
|
|
- if(!found)
|
|
|
+
|
|
|
+ // Print other characters normally.
|
|
|
+ if(!found_hyperlink)
|
|
|
{
|
|
|
- os << *p;
|
|
|
+ cmDocumentationPrintHTMLChar(os, *p++);
|
|
|
}
|
|
|
}
|
|
|
}
|