From effecf8007507ee2e90e5462ff6ef7dbc8871d3f Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Sat, 16 Feb 2019 00:36:18 -0500 Subject: New functions strings.CamelCase and strings.SnakeCase Signed-off-by: Dave Henderson --- docs-src/content/functions/strings.yml | 60 +++++++++++++++++- docs/content/functions/strings.md | 108 ++++++++++++++++++++++++++++++++- funcs/strings.go | 15 +++++ strings/strings.go | 36 +++++++++++ strings/strings_test.go | 15 +++++ tests/integration/strings_test.go | 11 ++++ 6 files changed, 242 insertions(+), 3 deletions(-) diff --git a/docs-src/content/functions/strings.yml b/docs-src/content/functions/strings.yml index 9359a956..773b7154 100644 --- a/docs-src/content/functions/strings.yml +++ b/docs-src/content/functions/strings.yml @@ -42,7 +42,7 @@ funcs: description: | Surrounds an input string with a single-quote (apostrophe) character (`'`). If the input is not a string, converts first. - `'` characters in the input are first escaped in the YAML-style (by repetition: `''`). + `'` characters in the input are first escaped in the YAML-style (by repetition: `''`). pipeline: true arguments: - name: in @@ -52,5 +52,63 @@ funcs: - | $ gomplate -i '{{ "in" | squote }}' 'in' + - | $ gomplate -i "{{ strings.Squote \"it's a banana\" }}" 'it''s a banana' + - name: strings.CamelCase + description: | + Converts a sentence to CamelCase, i.e. `The quick brown fox` becomes `TheQuickBrownFox`. + + All non-alphanumeric characters are stripped, and the beginnings of words are upper-cased. If the input begins with a lower-case letter, the result will also begin with a lower-case letter. + + See [CamelCase on Wikipedia](https://en.wikipedia.org/wiki/Camel_case) for more details. + pipeline: true + arguments: + - name: in + required: true + description: The input + examples: + - | + $ gomplate -i '{{ "Hello, World!" | strings.CamelCase }}' + HelloWorld + - | + $ gomplate -i '{{ "hello jello" | strings.CamelCase }}' + helloJello + - name: strings.SnakeCase + description: | + Converts a sentence to snake_case, i.e. `The quick brown fox` becomes `The_quick_brown_fox`. + + All non-alphanumeric characters are stripped, and spaces are replaced with an underscore (`_`). If the input begins with a lower-case letter, the result will also begin with a lower-case letter. + + See [Snake Case on Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details. + pipeline: true + arguments: + - name: in + required: true + description: The input + examples: + - | + $ gomplate -i '{{ "Hello, World!" | strings.SnakeCase }}' + Hello_world + - | + $ gomplate -i '{{ "hello jello" | strings.SnakeCase }}' + hello_jello + - name: strings.KebabCase + description: | + Converts a sentence to kebab-case, i.e. `The quick brown fox` becomes `The-quick-brown-fox`. + + All non-alphanumeric characters are stripped, and spaces are replaced with a hyphen (`-`). If the input begins with a lower-case letter, the result will also begin with a lower-case letter. + + See [Kebab Case on Wikipedia](https://en.wikipedia.org/wiki/Kebab_case) for more details. + pipeline: true + arguments: + - name: in + required: true + description: The input + examples: + - | + $ gomplate -i '{{ "Hello, World!" | strings.KebabCase }}' + Hello-world + - | + $ gomplate -i '{{ "hello jello" | strings.KebabCase }}' + hello-jello diff --git a/docs/content/functions/strings.md b/docs/content/functions/strings.md index a13ad138..8f019dfa 100644 --- a/docs/content/functions/strings.md +++ b/docs/content/functions/strings.md @@ -160,11 +160,11 @@ Returns an alphanumerically-sorted copy of a given string list. ### Usage ```go -strings.Sort list +strings.Sort list ``` ```go -list | strings.Sort +list | strings.Sort ``` ### Arguments @@ -355,6 +355,8 @@ in | strings.Squote ```console $ gomplate -i '{{ "in" | squote }}' 'in' +``` +```console $ gomplate -i "{{ strings.Squote \"it's a banana\" }}" 'it''s a banana' ``` @@ -528,6 +530,108 @@ $ gomplate -i '{{ "hello, world" | strings.Trunc 5 }}' hello ``` +## `strings.CamelCase` + +Converts a sentence to CamelCase, i.e. `The quick brown fox` becomes `TheQuickBrownFox`. + +All non-alphanumeric characters are stripped, and the beginnings of words are upper-cased. If the input begins with a lower-case letter, the result will also begin with a lower-case letter. + +See [CamelCase on Wikipedia](https://en.wikipedia.org/wiki/Camel_case) for more details. + +### Usage +```go +strings.CamelCase in +``` + +```go +in | strings.CamelCase +``` + +### Arguments + +| name | description | +|------|-------------| +| `in` | _(required)_ The input | + +### Examples + +```console +$ gomplate -i '{{ "Hello, World!" | strings.CamelCase }}' +HelloWorld +``` +```console +$ gomplate -i '{{ "hello jello" | strings.CamelCase }}' +helloJello +``` + +## `strings.SnakeCase` + +Converts a sentence to snake_case, i.e. `The quick brown fox` becomes `The_quick_brown_fox`. + +All non-alphanumeric characters are stripped, and spaces are replaced with an underscore (`_`). If the input begins with a lower-case letter, the result will also begin with a lower-case letter. + +See [Snake Case on Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details. + +### Usage +```go +strings.SnakeCase in +``` + +```go +in | strings.SnakeCase +``` + +### Arguments + +| name | description | +|------|-------------| +| `in` | _(required)_ The input | + +### Examples + +```console +$ gomplate -i '{{ "Hello, World!" | strings.SnakeCase }}' +Hello_world +``` +```console +$ gomplate -i '{{ "hello jello" | strings.SnakeCase }}' +hello_jello +``` + +## `strings.KebabCase` + +Converts a sentence to kebab-case, i.e. `The quick brown fox` becomes `The-quick-brown-fox`. + +All non-alphanumeric characters are stripped, and spaces are replaced with a hyphen (`-`). If the input begins with a lower-case letter, the result will also begin with a lower-case letter. + +See [Kebab Case on Wikipedia](https://en.wikipedia.org/wiki/Kebab_case) for more details. + +### Usage +```go +strings.KebabCase in +``` + +```go +in | strings.KebabCase +``` + +### Arguments + +| name | description | +|------|-------------| +| `in` | _(required)_ The input | + +### Examples + +```console +$ gomplate -i '{{ "Hello, World!" | strings.KebabCase }}' +Hello-world +``` +```console +$ gomplate -i '{{ "hello jello" | strings.KebabCase }}' +hello-jello +``` + ## `contains` **See [`strings.Contains](#strings-contains) for a pipeline-compatible version** diff --git a/funcs/strings.go b/funcs/strings.go index 0bb0924b..de00b4f1 100644 --- a/funcs/strings.go +++ b/funcs/strings.go @@ -224,3 +224,18 @@ func (f *StringFuncs) Squote(in interface{}) string { s = strings.Replace(s, `'`, `''`, -1) return fmt.Sprintf("'%s'", s) } + +// SnakeCase - +func (f *StringFuncs) SnakeCase(in interface{}) (string, error) { + return gompstrings.SnakeCase(conv.ToString(in)), nil +} + +// CamelCase - +func (f *StringFuncs) CamelCase(in interface{}) (string, error) { + return gompstrings.CamelCase(conv.ToString(in)), nil +} + +// KebabCase - +func (f *StringFuncs) KebabCase(in interface{}) (string, error) { + return gompstrings.KebabCase(conv.ToString(in)), nil +} diff --git a/strings/strings.go b/strings/strings.go index 3ee15c61..8c10865a 100644 --- a/strings/strings.go +++ b/strings/strings.go @@ -1,6 +1,7 @@ package strings import ( + "regexp" "sort" "strings" ) @@ -45,3 +46,38 @@ func Sort(list []string) []string { sorted.Sort() return sorted } + +var ( + spaces = regexp.MustCompile(`\s+`) + nonAlphaNum = regexp.MustCompile(`[^\pL\pN]+`) +) + +// SnakeCase - +func SnakeCase(in string) string { + s := casePrepare(in) + return spaces.ReplaceAllString(s, "_") +} + +// KebabCase - +func KebabCase(in string) string { + s := casePrepare(in) + return spaces.ReplaceAllString(s, "-") +} + +func casePrepare(in string) string { + in = strings.TrimSpace(in) + s := strings.ToLower(in) + // make sure the first letter remains lower- or upper-cased + s = strings.Replace(s, string(s[0]), string(in[0]), 1) + s = nonAlphaNum.ReplaceAllString(s, " ") + return strings.TrimSpace(s) +} + +// CamelCase - +func CamelCase(in string) string { + in = strings.TrimSpace(in) + s := strings.Title(in) + // make sure the first letter remains lower- or upper-cased + s = strings.Replace(s, string(s[0]), string(in[0]), 1) + return nonAlphaNum.ReplaceAllString(s, "") +} diff --git a/strings/strings_test.go b/strings/strings_test.go index f2afb2f5..dfcee552 100644 --- a/strings/strings_test.go +++ b/strings/strings_test.go @@ -39,3 +39,18 @@ func TestSort(t *testing.T) { expected = []string{"18", "42", "45"} assert.EqualValues(t, expected, Sort(in)) } + +func TestCaseFuncs(t *testing.T) { + testdata := []struct{ in, s, k, c string }{ + {" Foo bar ", "Foo_bar", "Foo-bar", "FooBar"}, + {"foo bar", "foo_bar", "foo-bar", "fooBar"}, + {" baz\tqux ", "baz_qux", "baz-qux", "bazQux"}, + {"Hello, World!", "Hello_world", "Hello-world", "HelloWorld"}, + {"grüne | Straße", "grüne_straße", "grüne-straße", "grüneStraße"}, + } + for _, d := range testdata { + assert.Equal(t, d.s, SnakeCase(d.in)) + assert.Equal(t, d.k, KebabCase(d.in)) + assert.Equal(t, d.c, CamelCase(d.in)) + } +} diff --git a/tests/integration/strings_test.go b/tests/integration/strings_test.go index affd8f32..4b9db835 100644 --- a/tests/integration/strings_test.go +++ b/tests/integration/strings_test.go @@ -49,3 +49,14 @@ func (s *StringsSuite) TestSlug(c *C) { `{{ strings.Slug "Hellö, Wôrld! Free @ last..." }}`) result.Assert(c, icmd.Expected{ExitCode: 0, Out: `hello-world-free-at-last`}) } + +func (s *StringsSuite) TestCaseFuncs(c *C) { + result := icmd.RunCommand(GomplateBin, "-i", + `{{ strings.CamelCase "Hellö, Wôrld! Free @ last..." }} +{{ strings.SnakeCase "Hellö, Wôrld! Free @ last..." }} +{{ strings.KebabCase "Hellö, Wôrld! Free @ last..." }}`) + result.Assert(c, icmd.Expected{ExitCode: 0, Out: `HellöWôrldFreeLast +Hellö_wôrld_free_last +Hellö-wôrld-free-last`}) + +} -- cgit v1.2.3