Documentation
¶
Overview ¶
Package kebabcase converts strings to kebab-case, a stdlib-only Go port of the npm "kebab-case" package (which is itself commonly interchanged with lodash.kebabcase). Kebab-case is the lower-cased, hyphen-delimited word form popular in URL slugs, CSS class and custom-property names, HTML data attributes, CLI flags, and file names, where a single ASCII hyphen visually separates words like the skewers of a kebab. The package exposes a single entry point, KebabCase, so it can be dropped in wherever the Node original was used without carrying any third-party dependencies.
A caller reaches for this package whenever a human-authored or programmatic identifier arrives in some other casing convention (camelCase, PascalCase, snake_case, "Title Case", or a mix of these) and a canonical kebab-case form is required. Typical uses are deriving a stable slug from a page title, normalizing component names, or turning a struct field name into a configuration key. Because the transformation is deterministic and depends only on the input runes, the same string always maps to the same result.
The algorithm walks the input rune by rune and builds the output in one pass. Word boundaries are detected in two ways: an explicit separator (a space, an underscore, or an existing hyphen) is emitted as a hyphen, and an implicit boundary is introduced by writing a hyphen before any uppercase letter that immediately follows a lowercase letter or a digit. Every letter is then lower-cased as it is written. A second pass, trimAndCollapse, collapses any run of consecutive hyphens down to a single hyphen and strips hyphens from the two ends, so the result never begins, ends, or contains a doubled delimiter.
The case rule is intentionally narrow, which gives it well-defined behavior on the awkward inputs. A run of adjacent capitals is treated as one word because no lowercase or digit precedes each capital, so "FOO" stays "foo" and an acronym-prefixed name such as "XMLHttpRequest" splits only where a lowercase precedes a capital, yielding "xmlhttp-request". A digit that precedes a capital does count as a boundary, so "foo123Bar" becomes "foo123-bar". Empty or whitespace-only input, and input consisting solely of separators such as "__foo__bar__" or "--foo--bar--", reduce cleanly to "" or to the trimmed "foo-bar" respectively.
Parity with the Node original is close for the common ASCII identifiers that motivate the library: "fooBar Baz" becomes "foo-bar-baz" and an already-kebab string round-trips unchanged. Two differences are worth noting. Case folding here uses Go's unicode.ToLower and the boundary tests use unicode.IsUpper, IsLower, and IsDigit, so classification follows Unicode rather than the JavaScript regular expressions used upstream; and this port does not insert the extra boundaries that lodash.kebabcase derives from more elaborate word-splitting, so its splitting is limited to case changes and the space, underscore, and hyphen separators described above.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func KebabCase ¶
KebabCase converts s to kebab-case.
Example ¶
This example shows the core behavior of KebabCase on a mixed-casing input. The space between the two words is turned into a hyphen, and the internal capital B in "fooBar" introduces an implicit word boundary because it follows a lowercase letter. Every letter is lower-cased as it is written. The result is the canonical kebab-case slug that the npm original would produce for the same string. This is the form typically used for URL slugs and CSS class names.
package main
import (
"fmt"
"github.com/malcolmston/express/kebabcase"
)
func main() {
fmt.Println(kebabcase.KebabCase("fooBar Baz"))
}
Output: foo-bar-baz
Example (Separators) ¶
This example demonstrates how separators and consecutive capitals are handled. Underscores are treated as word separators just like spaces, so "foo_bar" splits into two words. A run of adjacent capitals such as the "XML" prefix in "XMLHttpRequest" is treated as a single word because no lowercase letter or digit precedes each capital. A boundary is only inserted where a lowercase letter is followed by a capital, which is why the split falls between "xmlhttp" and "request". These rules make the transformation deterministic on acronym-heavy identifiers.
package main
import (
"fmt"
"github.com/malcolmston/express/kebabcase"
)
func main() {
fmt.Println(kebabcase.KebabCase("foo_bar"))
fmt.Println(kebabcase.KebabCase("XMLHttpRequest"))
fmt.Println(kebabcase.KebabCase("foo123Bar"))
}
Output: foo-bar xmlhttp-request foo123-bar
Example (Trimming) ¶
This example covers the trimming and collapsing edge cases. Leading and trailing separators are stripped from the result, and any run of repeated separators collapses down to a single hyphen. Input that is empty or made up entirely of whitespace reduces to the empty string. This mirrors how the second normalization pass guarantees the output never begins, ends, or contains a doubled delimiter. The quoted printing makes the empty result visible in the output.
package main
import (
"fmt"
"github.com/malcolmston/express/kebabcase"
)
func main() {
fmt.Printf("%q\n", kebabcase.KebabCase("__foo__bar__"))
fmt.Printf("%q\n", kebabcase.KebabCase("--foo--bar--"))
fmt.Printf("%q\n", kebabcase.KebabCase(" "))
}
Output: "foo-bar" "foo-bar" ""
Types ¶
This section is empty.