Skip to content

Commit 62efd7f

Browse files
committed
Add option to disable trimming of dashes and underscores
1 parent 8f2fa2f commit 62efd7f

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

slug.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ var (
3838
// Default is true.
3939
Lowercase = true
4040

41+
// DisableMultipleDashTrim defines if multiple dashes should be preserved.
42+
// Default is false (multiple dashes will be replaced with single dash).
43+
DisableMultipleDashTrim = false
44+
45+
// DisableEndsTrim defines if the slug should keep leading and trailing
46+
// dashes and underscores. Default is false (trim enabled).
47+
DisableEndsTrim = false
48+
4149
// Append timestamp to the end in order to make slug unique
4250
// Default is false
4351
AppendTimestamp = false
@@ -126,8 +134,12 @@ func MakeLang(s string, lang string) (slug string) {
126134

127135
// Process all remaining symbols
128136
slug = regexpNonAuthorizedChars.ReplaceAllString(slug, "-")
129-
slug = regexpMultipleDashes.ReplaceAllString(slug, "-")
130-
slug = strings.Trim(slug, "-_")
137+
if !DisableMultipleDashTrim {
138+
slug = regexpMultipleDashes.ReplaceAllString(slug, "-")
139+
}
140+
if !DisableEndsTrim {
141+
slug = strings.Trim(slug, "-_")
142+
}
131143

132144
if MaxLength > 0 && EnableSmartTruncate {
133145
slug = smartTruncate(slug)
@@ -145,7 +157,7 @@ func MakeLang(s string, lang string) (slug string) {
145157
// order. Many passes, on one substitution another one could apply.
146158
func Substitute(s string, sub map[string]string) (buf string) {
147159
buf = s
148-
var keys = make([]string, 0, len(sub))
160+
keys := make([]string, 0, len(sub))
149161
for k := range sub {
150162
keys = append(keys, k)
151163
}

slug_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,52 @@ func TestIsSlug(t *testing.T) {
472472
})
473473
}
474474

475+
func TestSlugMakeDisableTrimOptions(t *testing.T) {
476+
testCases := []struct {
477+
name string
478+
in string
479+
want string
480+
disableMultipleDash bool
481+
disableEndsTrim bool
482+
}{
483+
// Test multiple dash trim
484+
{"multiple dashes preserved", "test--slug", "test--slug", true, false},
485+
{"multiple dashes and spaces", "spaces converted to--dashes", "spaces--converted--to--dashes", true, false},
486+
{"symbols to multiple dashes", "symbols!!!replaced", "symbols---replaced", true, false},
487+
{"only dashes multiple", "----", "", true, false},
488+
{"only underscores multiple", "____", "", true, false},
489+
490+
// Test end trim
491+
{"leading/trailing dashes", "-test-slug-", "-test-slug-", false, true},
492+
{"leading/trailing underscores", "_test_slug_", "_test_slug_", false, true},
493+
{"mixed endings", "-_mixed_-", "-_mixed_-", false, true},
494+
{"only dashes end", "----", "-", false, true},
495+
{"only underscores end", "____", "____", false, true},
496+
497+
// Test both options together
498+
{"both options enabled", "--test---slug--", "--test---slug--", true, true},
499+
{"multiple types of edges", "__test---slug--", "__test---slug--", true, true},
500+
{"only dashes both", "----", "----", true, true},
501+
{"only underscores both", "____", "____", true, true},
502+
}
503+
504+
for _, tc := range testCases {
505+
t.Run(tc.name, func(t *testing.T) {
506+
DisableMultipleDashTrim = tc.disableMultipleDash
507+
DisableEndsTrim = tc.disableEndsTrim
508+
defer func() {
509+
DisableMultipleDashTrim = false
510+
DisableEndsTrim = false
511+
}()
512+
513+
got := Make(tc.in)
514+
if got != tc.want {
515+
t.Errorf("Make(%#v) = %#v; want %#v", tc.in, got, tc.want)
516+
}
517+
})
518+
}
519+
}
520+
475521
func BenchmarkMakeShortAscii(b *testing.B) {
476522
b.ReportAllocs()
477523
for n := 0; n < b.N; n++ {

0 commit comments

Comments
 (0)