Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F13780868
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Jan 30, 3:05 PM (3 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3610830
Attached To
rWC Write.as Web Core
Event Timeline
Log In to Comment