62 lines
839 B
Go
62 lines
839 B
Go
package utils
|
|
|
|
import (
|
|
"unicode"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
type buffer struct {
|
|
r []byte
|
|
runeBytes [utf8.UTFMax]byte
|
|
}
|
|
|
|
func (b *buffer) write(r rune) {
|
|
if r < utf8.RuneSelf {
|
|
b.r = append(b.r, byte(r))
|
|
return
|
|
}
|
|
n := utf8.EncodeRune(b.runeBytes[0:], r)
|
|
b.r = append(b.r, b.runeBytes[0:n]...)
|
|
}
|
|
|
|
func (b *buffer) indent() {
|
|
if len(b.r) > 0 {
|
|
b.r = append(b.r, '_')
|
|
}
|
|
}
|
|
|
|
func Underscore(s string) string {
|
|
b := buffer{
|
|
r: make([]byte, 0, len(s)),
|
|
}
|
|
var m rune
|
|
var w bool
|
|
for _, ch := range s {
|
|
if unicode.IsUpper(ch) {
|
|
if m != 0 {
|
|
if !w {
|
|
b.indent()
|
|
w = true
|
|
}
|
|
b.write(m)
|
|
}
|
|
m = unicode.ToLower(ch)
|
|
} else {
|
|
if m != 0 {
|
|
b.indent()
|
|
b.write(m)
|
|
m = 0
|
|
w = false
|
|
}
|
|
b.write(ch)
|
|
}
|
|
}
|
|
if m != 0 {
|
|
if !w {
|
|
b.indent()
|
|
}
|
|
b.write(m)
|
|
}
|
|
return string(b.r)
|
|
}
|