Skip to content

Commit 3740e43

Browse files
committed
Implement textcase.KebabCase(), a "kebab-case" naming convention
1 parent cc18b18 commit 3740e43

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![GoDoc Widget]][GoDoc]
44

5-
Golang pkg to convert any text input to camelCase, PascalCase or snake_case naming convention. Removes all whitespaces and special characters. Supports Unicode characters.
5+
Golang pkg to convert any text input to **camelCase**, **PascalCase**, **snake_case** or **kebab-case** naming convention. Removes all whitespaces and special characters. Supports Unicode characters.
66

77
## Usage
88
```go
@@ -16,6 +16,9 @@ textcase.PascalCase("Hello World!")
1616

1717
textcase.SnakeCase("Hello World!")
1818
// hello_world
19+
20+
textcase.KebabCase("Hello World!")
21+
// hello-world
1922
```
2023

2124
## Unicode support

kebab.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package textcase
2+
3+
import (
4+
"bytes"
5+
"unicode"
6+
"unicode/utf8"
7+
)
8+
9+
// Converts input string to "kebab-case" naming convention.
10+
// Removes all whitespace and special characters. Supports Unicode characters.
11+
func KebabCase(str string) string {
12+
var b bytes.Buffer
13+
14+
state := idle
15+
for i := 0; i < len(str); {
16+
r, size := utf8.DecodeRuneInString(str[i:])
17+
i += size
18+
state = state.next(r)
19+
switch state {
20+
case firstAlphaNum, alphaNum:
21+
b.WriteRune(unicode.ToLower(r))
22+
case delimiter:
23+
b.WriteByte('-')
24+
}
25+
}
26+
if (state == idle || state == delimiter) && b.Len() > 0 {
27+
b.Truncate(b.Len() - 1)
28+
}
29+
30+
return b.String()
31+
}

textcase_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,26 @@ func TestTextCases(t *testing.T) {
2929
}
3030

3131
for _, test := range tt {
32+
// camelCase
3233
if got := CamelCase(test.in); got != test.camel {
3334
t.Errorf("unexpected camelCase for input(%q), got %q, want %q", test.in, got, test.camel)
3435
}
35-
if got := PascalCase(test.in); got != strings.Title(test.camel) {
36-
t.Errorf("unexpected PascalCase for input(%q), got %q, want %q", test.in, got, strings.Title(test.camel))
36+
37+
// PascalCase
38+
testPascal := strings.Title(test.camel)
39+
if got := PascalCase(test.in); got != testPascal {
40+
t.Errorf("unexpected PascalCase for input(%q), got %q, want %q", test.in, got, testPascal)
3741
}
42+
43+
// snake_case
3844
if got := SnakeCase(test.in); got != test.snake {
3945
t.Errorf("unexpected snake_case for input(%q), got %q, want %q", test.in, got, test.snake)
4046
}
47+
48+
// kebab-case
49+
testKebab := strings.ReplaceAll(test.snake, "_", "-")
50+
if got := KebabCase(test.in); got != testKebab {
51+
t.Errorf("unexpected kebab-case for input(%q), got %q, want %q", test.in, got, testKebab)
52+
}
4153
}
4254
}

0 commit comments

Comments
 (0)