diff --git a/web/helpers.go b/web/helpers.go
index 4e7d48e..af98e0e 100644
--- a/web/helpers.go
+++ b/web/helpers.go
@@ -5,16 +5,20 @@ import (
"github.com/jhillyerd/inbucket/log"
"html"
"html/template"
+ "regexp"
"strings"
"time"
)
var TemplateFuncs = template.FuncMap{
"friendlyTime": friendlyTime,
- "reverse": reverse,
- "textToHtml": textToHtml,
+ "reverse": reverse,
+ "textToHtml": textToHtml,
}
+// From http://daringfireball.net/2010/07/improved_regex_for_matching_urls
+var urlRE = regexp.MustCompile("(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))")
+
// Friendly date & time rendering
func friendlyTime(t time.Time) template.HTML {
ty, tm, td := t.Date()
@@ -45,6 +49,13 @@ func reverse(name string, things ...interface{}) string {
// HTML display
func textToHtml(text string) template.HTML {
text = html.EscapeString(text)
+ text = urlRE.ReplaceAllStringFunc(text, wrapUrl)
replacer := strings.NewReplacer("\r\n", "
\n", "\r", "
\n", "\n", "
\n")
return template.HTML(replacer.Replace(text))
}
+
+// wrapUrl wraps a tag around the provided URL
+func wrapUrl(url string) string {
+ unescaped := strings.Replace(url, "&", "&", -1)
+ return fmt.Sprintf("%s", unescaped, url)
+}
diff --git a/web/helpers_test.go b/web/helpers_test.go
index 44936b0..b50a838 100644
--- a/web/helpers_test.go
+++ b/web/helpers_test.go
@@ -2,18 +2,28 @@ package web
import (
"github.com/stretchrcom/testify/assert"
+ "html/template"
"testing"
)
func TestTextToHtml(t *testing.T) {
// Identity
- assert.Equal(t, textToHtml("html"), "html")
+ assert.Equal(t, textToHtml("html"), template.HTML("html"))
// Check it escapes
- assert.Equal(t, textToHtml(""), "<html>")
+ assert.Equal(t, textToHtml(""), template.HTML("<html>"))
// Check for linebreaks
- assert.Equal(t, textToHtml("line\nbreak"), "line
\nbreak")
- assert.Equal(t, textToHtml("line\r\nbreak"), "line
\nbreak")
- assert.Equal(t, textToHtml("line\rbreak"), "line
\nbreak")
+ assert.Equal(t, textToHtml("line\nbreak"), template.HTML("line
\nbreak"))
+ assert.Equal(t, textToHtml("line\r\nbreak"), template.HTML("line
\nbreak"))
+ assert.Equal(t, textToHtml("line\rbreak"), template.HTML("line
\nbreak"))
+}
+
+func TestURLDetection(t *testing.T) {
+ assert.Equal(t,
+ textToHtml("http://google.com/"),
+ template.HTML("http://google.com/"))
+ assert.Equal(t,
+ textToHtml("http://a.com/?q=a&n=v"),
+ template.HTML("http://a.com/?q=a&n=v"))
}