summaryrefslogtreecommitdiff
path: root/internal/text
diff options
context:
space:
mode:
Diffstat (limited to 'internal/text')
-rw-r--r--internal/text/plain_test.go13
-rw-r--r--internal/text/util.go30
2 files changed, 41 insertions, 2 deletions
diff --git a/internal/text/plain_test.go b/internal/text/plain_test.go
index 48280bb44..fac54a38e 100644
--- a/internal/text/plain_test.go
+++ b/internal/text/plain_test.go
@@ -36,6 +36,8 @@ const (
moreComplexExpected = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br><br><a href=\"http://localhost:8080/tags/hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a><br><br>Text<br><br>:rainbow:</p>"
withUTF8Link = "here's a link with utf-8 characters in it: https://example.org/söme_url"
withUTF8LinkExpected = "<p>here's a link with utf-8 characters in it: <a href=\"https://example.org/s%C3%B6me_url\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://example.org/söme_url</a></p>"
+ withFunkyTags = "#hashtag1 pee #hashtag2\u200Bpee #hashtag3|poo #hashtag4\uFEFFpoo"
+ withFunkyTagsExpected = "<p><a href=\"http://localhost:8080/tags/hashtag1\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag1</span></a> pee <a href=\"http://localhost:8080/tags/hashtag2\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag2</span></a>\u200bpee <a href=\"http://localhost:8080/tags/hashtag3\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag3</span></a>|poo <a href=\"http://localhost:8080/tags/hashtag4\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag4</span></a>\ufeffpoo</p>"
)
type PlainTestSuite struct {
@@ -136,6 +138,17 @@ func (suite *PlainTestSuite) TestDeriveHashtagsOK() {
suite.Equal("올빼미", tags[0].Name)
}
+func (suite *PlainTestSuite) TestFunkyTags() {
+ formatted := suite.FromPlain(withFunkyTags)
+ suite.Equal(withFunkyTagsExpected, formatted.HTML)
+
+ tags := formatted.Tags
+ suite.Equal("hashtag1", tags[0].Name)
+ suite.Equal("hashtag2", tags[1].Name)
+ suite.Equal("hashtag3", tags[2].Name)
+ suite.Equal("hashtag4", tags[3].Name)
+}
+
func (suite *PlainTestSuite) TestDeriveMultiple() {
statusText := `Another test @foss_satan@fossbros-anonymous.io
diff --git a/internal/text/util.go b/internal/text/util.go
index 204c64838..af45cfaf0 100644
--- a/internal/text/util.go
+++ b/internal/text/util.go
@@ -38,8 +38,34 @@ func isPermittedInHashtag(r rune) bool {
// is a recognized break character for before
// or after a #hashtag.
func isHashtagBoundary(r rune) bool {
- return unicode.IsSpace(r) ||
- (unicode.IsPunct(r) && r != '_')
+ switch {
+
+ // Zero width space.
+ case r == '\u200B':
+ return true
+
+ // Zero width no-break space.
+ case r == '\uFEFF':
+ return true
+
+ // Pipe character sometimes
+ // used as workaround.
+ case r == '|':
+ return true
+
+ // Standard Unicode white space.
+ case unicode.IsSpace(r):
+ return true
+
+ // Non-underscore punctuation.
+ case unicode.IsPunct(r) && r != '_':
+ return true
+
+ // Not recognized
+ // hashtag boundary.
+ default:
+ return false
+ }
}
// isMentionBoundary returns true if rune r