From 6d152a8480a118f63633bc340d1d542b98ae2870 Mon Sep 17 00:00:00 2001 From: Assil Ksiksi Date: Mon, 3 Mar 2025 22:32:29 -0500 Subject: [PATCH] add indentnonempty function --- docs/strings.md | 12 ++++++++++++ functions.go | 31 ++++++++++++++++--------------- strings.go | 12 ++++++++++++ strings_test.go | 15 +++++++++++++++ 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/docs/strings.md b/docs/strings.md index 2e0f455d..b43b2cdb 100644 --- a/docs/strings.md +++ b/docs/strings.md @@ -256,6 +256,18 @@ indent 4 $lots_of_text The above will indent every line of text by 4 space characters. +## indentnonempty + +The `indentnonempty` behaves the same as `indent`, but only indents non-empty +lines (i.e., lines containing non-space characters). Empty lines are kept as-is. + +``` +indentnonempty 4 $lots_of_text +``` + +This is useful when indenting generated code as it avoids adding spaces to empty +lines. + ## nindent The `nindent` function is the same as the indent function, but prepends a new diff --git a/functions.go b/functions.go index cda47d26..2aa9db73 100644 --- a/functions.go +++ b/functions.go @@ -149,21 +149,22 @@ var genericMap = map[string]interface{}{ "wrap": func(l int, s string) string { return util.Wrap(s, l) }, "wrapWith": func(l int, sep, str string) string { return util.WrapCustom(str, l, sep, true) }, // Switch order so that "foobar" | contains "foo" - "contains": func(substr string, str string) bool { return strings.Contains(str, substr) }, - "hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) }, - "hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) }, - "quote": quote, - "squote": squote, - "cat": cat, - "indent": indent, - "nindent": nindent, - "replace": replace, - "plural": plural, - "sha1sum": sha1sum, - "sha256sum": sha256sum, - "sha512sum": sha512sum, - "adler32sum": adler32sum, - "toString": strval, + "contains": func(substr string, str string) bool { return strings.Contains(str, substr) }, + "hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) }, + "hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) }, + "quote": quote, + "squote": squote, + "cat": cat, + "indent": indent, + "indentnonempty": indentnonempty, + "nindent": nindent, + "replace": replace, + "plural": plural, + "sha1sum": sha1sum, + "sha256sum": sha256sum, + "sha512sum": sha512sum, + "adler32sum": adler32sum, + "toString": strval, // Wrap Atoi to stop errors. "atoi": func(a string) int { i, _ := strconv.Atoi(a); return i }, diff --git a/strings.go b/strings.go index e0ae628c..5f12c79f 100644 --- a/strings.go +++ b/strings.go @@ -111,6 +111,18 @@ func indent(spaces int, v string) string { return pad + strings.Replace(v, "\n", "\n"+pad, -1) } +func indentnonempty(spaces int, v string) string { + pad := strings.Repeat(" ", spaces) + lines := strings.Split(v, "\n") + for i, line := range lines { + if strings.TrimSpace(line) == "" { + continue + } + lines[i] = pad + line + } + return strings.Join(lines, "\n") +} + func nindent(spaces int, v string) string { return "\n" + indent(spaces, v) } diff --git a/strings_test.go b/strings_test.go index a75ab086..f5af36d9 100644 --- a/strings_test.go +++ b/strings_test.go @@ -252,6 +252,21 @@ func TestIndent(t *testing.T) { } } +func TestIndentNonEmpty(t *testing.T) { + tpl := `{{indentnonempty 4 "a\nb\nc"}}` + if err := runt(tpl, " a\n b\n c"); err != nil { + t.Error(err) + } + tpl = `{{indentnonempty 4 "a\n \nb\nc"}}` + if err := runt(tpl, " a\n \n b\n c"); err != nil { + t.Error(err) + } + tpl = `{{indentnonempty 4 "a\n \nb\nc\n"}}` + if err := runt(tpl, " a\n \n b\n c\n"); err != nil { + t.Error(err) + } +} + func TestNindent(t *testing.T) { tpl := `{{nindent 4 "a\nb\nc"}}` if err := runt(tpl, "\n a\n b\n c"); err != nil {