From 49bf0b9e3d48dd650daa924a238fccc1bc3324d7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 16 Oct 2006 14:52:31 -0400 Subject: [PATCH] ENH: Make hyperlinks in documentation active when generated into HTML documents. This addresses bug#3906. --- Source/cmDocumentation.cxx | 83 +++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 283b020ec..392ba4b68 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -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", "
", 0}, {0,0,0} }; - for(const char* p = text; *p; ++p) + for(const cmDocumentationEntry* op = escapes; op->name; ++op) { - bool found = false; - for(const cmDocumentationEntry* op = escapes; !found && op->name; ++op) + if(op->name[0] == c) { - if(op->name[0] == *p) + 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 << ""; + + // The name of the hyperlink is the text itself. + for(const char* c = begin; c != end; ++c) + { + cmDocumentationPrintHTMLChar(os, *c); + } + os << ""; + + // 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(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++); } } }