-
Notifications
You must be signed in to change notification settings - Fork 27
/
slugify.go
81 lines (74 loc) · 2.34 KB
/
slugify.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package strutil
// Slugify converts a string to a slug which is useful in URLs, filenames.
// It removes accents, converts to lower case, remove the characters which
// are not letters or numbers and replaces spaces with "-".
//
// Example:
// strutil.Slugify("'We löve Motörhead'") //Output: we-love-motorhead
//
// Normalzation is done with strutil.ReplaceAccents function using a rune replacement map
// You can use the following code for better normalization before strutil.Slugify()
//
// str := "'We löve Motörhead'"
// t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
// str = transform.String(t, str) //We love Motorhead
//
// Slugify doesn't support transliteration. You should use a transliteration
// library before Slugify like github.com/rainycape/unidecode
//
// Example:
// import "github.com/rainycape/unidecode"
//
// str := unidecode.Unidecode("你好, world!")
// strutil.Slugify(str) //Output: ni-hao-world
//
func Slugify(str string) string {
return SlugifySpecial(str, "-")
}
// SlugifySpecial converts a string to a slug with the delimiter.
// It removes accents, converts string to lower case, remove the characters
// which are not letters or numbers and replaces spaces with the delimiter.
//
// Example:
// strutil.SlugifySpecial("'We löve Motörhead'", "-") //Output: we-love-motorhead
//
// SlugifySpecial doesn't support transliteration. You should use a transliteration
// library before SlugifySpecial like github.com/rainycape/unidecode
//
// Example:
// import "github.com/rainycape/unidecode"
//
// str := unidecode.Unidecode("你好, world!")
// strutil.SlugifySpecial(str, "-") //Output: ni-hao-world
func SlugifySpecial(str string, delimiter string) string {
str = RemoveAccents(str)
delBytes := []byte(delimiter)
n := make([]byte, 0, len(str))
isPrevSpace := false
for _, r := range str {
//toLowerCase
if r >= 'A' && r <= 'Z' {
r -= 'A' - 'a'
}
//replace non-alphanum chars with delimiter
switch {
case (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9'):
n = append(n, byte(int8(r)))
isPrevSpace = false
case !isPrevSpace:
if len(n) > 0 {
n = append(n, delBytes...)
}
fallthrough
default:
isPrevSpace = true
}
}
//trim right
ln := len(n)
ld := len(delimiter)
if ln >= ld && string(n[ln-ld:]) == delimiter {
n = n[:ln-ld]
}
return string(n)
}