ENH: Make hyperlinks in documentation active when generated into HTML documents. This addresses bug#3906.

This commit is contained in:
Brad King 2006-10-16 14:52:31 -04:00
parent e55ff93748
commit 49bf0b9e3d
1 changed files with 74 additions and 9 deletions

View File

@ -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[] =
{
{"<", "&lt;", 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)
{
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 << "<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)
{
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(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++);
}
}
}