Page MenuHomeMusing Studio

No OneTemporary

diff --git a/category/tags.go b/category/tags.go
index 9b99248..a3a092a 100644
--- a/category/tags.go
+++ b/category/tags.go
@@ -1,26 +1,47 @@
package category
import (
"strings"
"unicode"
)
// titleFromHashtag generates an all-lowercase title, with spaces inserted based on initial capitalization -- e.g.
// "MyWordyTag" becomes "my wordy tag".
func titleFromHashtag(hashtag string) string {
var t strings.Builder
var prev rune
for i, c := range hashtag {
if unicode.IsUpper(c) {
if i > 0 && !unicode.IsUpper(prev) {
// Insert space if previous rune wasn't also uppercase (e.g. an abbreviation)
t.WriteRune(' ')
}
t.WriteRune(unicode.ToLower(c))
} else {
t.WriteRune(c)
}
prev = c
}
return t.String()
}
+
+// HashtagFromTitle generates a valid single-word, camelCase hashtag from a title (which might include spaces,
+// punctuation, etc.).
+func HashtagFromTitle(title string) string {
+ var t strings.Builder
+ var prev rune
+ for _, c := range title {
+ if !unicode.IsLetter(c) && !unicode.IsNumber(c) {
+ prev = c
+ continue
+ }
+ if unicode.IsSpace(prev) {
+ // Uppercase next word
+ t.WriteRune(unicode.ToUpper(c))
+ } else {
+ t.WriteRune(c)
+ }
+ prev = c
+ }
+ return t.String()
+}
diff --git a/category/tags_test.go b/category/tags_test.go
index 9889cfc..92a45c1 100644
--- a/category/tags_test.go
+++ b/category/tags_test.go
@@ -1,31 +1,60 @@
package category
import "testing"
func TestTitleFromHashtag(t *testing.T) {
tests := []struct {
name string
hashtag string
expTitle string
}{
{"proper noun", "Jane", "jane"},
{"full name", "JaneDoe", "jane doe"},
{"us words", "unitedStates", "united states"},
{"usa", "USA", "usa"},
{"us monoword", "unitedstates", "unitedstates"},
{"100dto", "100DaysToOffload", "100 days to offload"},
{"iphone", "iPhone", "iphone"},
{"ilike", "iLikeThis", "i like this"},
{"abird", "aBird", "a bird"},
{"all caps", "URGENT", "urgent"},
{"smartphone", "スマートフォン", "スマートフォン"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := titleFromHashtag(test.hashtag)
if res != test.expTitle {
t.Fatalf("#%s: got '%s' expected '%s'", test.hashtag, res, test.expTitle)
}
})
}
}
+
+func TestHashtagFromTitle(t *testing.T) {
+ tests := []struct {
+ name string
+ title string
+ expHashtag string
+ }{
+ {"proper noun", "Jane", "Jane"},
+ {"full name", "Jane Doe", "JaneDoe"},
+ {"us upper words", "United States", "UnitedStates"},
+ {"us lower words", "united states", "unitedStates"},
+ {"usa", "USA", "USA"},
+ {"100dto", "100 Days To Offload", "100DaysToOffload"},
+ {"iphone", "iPhone", "iPhone"},
+ {"ilike", "I like this", "ILikeThis"},
+ {"abird", "a Bird", "aBird"},
+ {"all caps", "URGENT", "URGENT"},
+ {"punctuation", "John’s Stories", "JohnsStories"},
+ {"smartphone", "スマートフォン", "スマートフォン"},
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ res := HashtagFromTitle(test.title)
+ if res != test.expHashtag {
+ t.Fatalf("%s: got '%s' expected '%s'", test.title, res, test.expHashtag)
+ }
+ })
+ }
+}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Jan 30, 3:05 PM (5 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3610830

Event Timeline