summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/developer/tests/test-hashtags.md20
-rw-r--r--model/utils.go6
-rw-r--r--model/utils_test.go24
-rw-r--r--web/react/utils/text_formatting.jsx2
4 files changed, 48 insertions, 4 deletions
diff --git a/doc/developer/tests/test-hashtags.md b/doc/developer/tests/test-hashtags.md
new file mode 100644
index 000000000..0c26042ba
--- /dev/null
+++ b/doc/developer/tests/test-hashtags.md
@@ -0,0 +1,20 @@
+# Hashtag Testing
+
+Hashtags in Mattermosts should render as specified below.
+
+#### These strings should auto-link:
+
+#testing
+#testing123
+#test-test
+#test_test
+#test! (punctuation should be excluded from linking)
+#test1 #test2
+#hüllo
+
+#### These strings should not auto-link:
+
+#123test
+#?test
+#-test
+
diff --git a/model/utils.go b/model/utils.go
index 5596b06ff..617c95efd 100644
--- a/model/utils.go
+++ b/model/utils.go
@@ -273,9 +273,9 @@ func Etag(parts ...interface{}) string {
return etag
}
-var validHashtag = regexp.MustCompile(`^(#[A-Za-z]+[A-Za-z0-9_\-]*[A-Za-z0-9])$`)
-var puncStart = regexp.MustCompile(`^[.,()&$!\[\]{}':;\\]+`)
-var puncEnd = regexp.MustCompile(`[.,()&$#!\[\]{}';\\]+$`)
+var validHashtag = regexp.MustCompile(`^(#[A-Za-zäöüÄÖÜß]+[A-Za-z0-9äöüÄÖÜß_\-]*[A-Za-z0-9äöüÄÖÜß])$`)
+var puncStart = regexp.MustCompile(`^[.,()&$!\?\[\]{}':;\\]+`)
+var puncEnd = regexp.MustCompile(`[.,()&$#!\?\[\]{}';\\]+$`)
func ParseHashtags(text string) (string, string) {
words := strings.Fields(text)
diff --git a/model/utils_test.go b/model/utils_test.go
index aab535fc9..24ee4b7a6 100644
--- a/model/utils_test.go
+++ b/model/utils_test.go
@@ -81,3 +81,27 @@ func TestEtag(t *testing.T) {
t.Fatal()
}
}
+
+var hashtags map[string]string = map[string]string{
+ "#test": "#test",
+ "test": "",
+ "#test123": "#test123",
+ "#123test123": "",
+ "#test-test": "#test-test",
+ "#test?": "#test",
+ "hi #there": "#there",
+ "#bug #idea": "#bug #idea",
+ "#bug or #gif!": "#bug #gif",
+ "#hüllo": "#hüllo",
+ "#?test": "",
+ "#-test": "",
+ "#yo_yo": "#yo_yo",
+}
+
+func TestParseHashtags(t *testing.T) {
+ for input, output := range hashtags {
+ if o, _ := ParseHashtags(input); o != output {
+ t.Fatal("expected=" + output + " actual=" + o)
+ }
+ }
+}
diff --git a/web/react/utils/text_formatting.jsx b/web/react/utils/text_formatting.jsx
index f0bd46f9d..e837ded53 100644
--- a/web/react/utils/text_formatting.jsx
+++ b/web/react/utils/text_formatting.jsx
@@ -256,7 +256,7 @@ function autolinkHashtags(text, tokens) {
return prefix + alias;
}
- return output.replace(/(^|\W)(#[a-zA-Z][a-zA-Z0-9.\-_]*)\b/g, replaceHashtagWithToken);
+ return output.replace(/(^|\W)(#[a-zA-ZäöüÄÖÜß][a-zA-Z0-9äöüÄÖÜß.\-_]*)\b/g, replaceHashtagWithToken);
}
const puncStart = /^[.,()&$!\[\]{}':;\\]+/;