Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func main() {

- `Colors` must have the same number of entries as `Title` — `NewCmdBanner` returns an error otherwise.
- `Title` segments are concatenated with no separator, so include spacing in the segments themselves if you want it.
- `TopPadding` defaults to `true`, which adds a single leading newline before the rendered output (use `WithZeroPadding()` to disable this).
- `TopPadding` defaults to `1`, which adds a single leading newline before the rendered output (use `WithPadding(0, 0)` to disable this).
- `CmdBanner` and `PrintCmdBanner` both return an error if `FontPath` fails to load or rendering fails (e.g. `FontName` can't be found).

#### Banner functional options
Expand All @@ -140,7 +140,8 @@ func main() {
| `WithColors(colors ...string)` | Sets the color palette, one per `Title` segment. Each string is resolved with `ResolveColor`. |
| `WithFont(name string)` | Selects a builtin or already-loaded font by name. |
| `WithLocalFont(name, path string)` | Sets the font name *and* a directory to load additional fonts from. |
| `WithZeroPadding()` | Disables the default leading newline (`TopPadding = false`). |
| `WithPadding(top, bottom int)` | Sets the number of newlines before (`top`) and after (`bottom`) the rendered output. |
| `WithZeroPadding()` | Convenience wrapper for `WithPadding(0, 0)` to disable both top and bottom padding. |

#### Screenshot

Expand Down
29 changes: 22 additions & 7 deletions banner.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ type Banner struct {
// FontPath, if set, is an on-disk directory to load additional fonts
// from (in addition to the embedded builtin fonts) before rendering.
FontPath string
// TopPadding, if true, adds a single leading newline before the
// TopPadding is the number of leading newlines to add before the
// rendered output. It does not affect kerning or layout.
TopPadding bool
TopPadding int
// BottomPadding is the number of trailing newlines to add after the
// rendered output.
BottomPadding int
}

// BannerOptions configures a Banner via the functional options pattern.
Expand Down Expand Up @@ -56,13 +59,21 @@ func WithLocalFont(f string, p string) BannerOptions {
}
}

// WithZeroPadding disables the leading newline added by default when TopPadding is true.
func WithZeroPadding() BannerOptions {
// WithPadding sets the number of newlines to add before (top) and after
// (bottom) the rendered output. Pass 0 to disable padding on either side.
func WithPadding(top, bottom int) BannerOptions {
return func(b *Banner) {
b.TopPadding = false
b.TopPadding = top
b.BottomPadding = bottom
}
}

// WithZeroPadding is a convenience wrapper around WithPadding(0, 0) that
// disables both top and bottom padding.
func WithZeroPadding() BannerOptions {
return WithPadding(0, 0)
}

// NewCmdBanner creates a Banner with sensible defaults for CLI tool banners.
// Title entries represent command and subcommand names (e.g., ["cmd", "sub"]).
// Colors must match the number of Title entries.
Expand All @@ -71,7 +82,7 @@ func NewCmdBanner(title []string, options ...BannerOptions) (*Banner, error) {
Title: title,
Colors: []color.Color{ColorCyan, TrueColorPink206},
FontName: "smallsmursh",
TopPadding: true,
TopPadding: 1,
}
for _, o := range options {
o(b)
Expand Down Expand Up @@ -119,7 +130,7 @@ func CmdBanner(b *Banner) (string, error) {
figletOptions.FontColor = figletColors

var renderedString strings.Builder
if b.TopPadding {
for i := 0; i < b.TopPadding; i++ {
renderedString.WriteByte('\n')
}

Expand All @@ -129,6 +140,10 @@ func CmdBanner(b *Banner) (string, error) {
}
renderedString.WriteString(asciiString)

for i := 0; i < b.BottomPadding; i++ {
renderedString.WriteByte('\n')
}

return renderedString.String(), nil
}

Expand Down
78 changes: 78 additions & 0 deletions banner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package gofiglet

import (
"image/color"
"strings"
"testing"
)

func TestNewCmdBanner_DefaultPadding(t *testing.T) {
b, err := NewCmdBanner([]string{"Test"}, WithColors([]color.Color{ColorCyan}))
if err != nil {
t.Fatalf("NewCmdBanner() error = %v", err)
}
if b.TopPadding != 1 {
t.Errorf("default TopPadding = %d, want 1", b.TopPadding)
}
if b.BottomPadding != 0 {
t.Errorf("default BottomPadding = %d, want 0", b.BottomPadding)
}
}

func TestWithPadding(t *testing.T) {
b, err := NewCmdBanner([]string{"Test"}, WithPadding(3, 2), WithColors([]color.Color{ColorCyan}))
if err != nil {
t.Fatalf("NewCmdBanner() error = %v", err)
}
if b.TopPadding != 3 {
t.Errorf("TopPadding = %d, want 3", b.TopPadding)
}
if b.BottomPadding != 2 {
t.Errorf("BottomPadding = %d, want 2", b.BottomPadding)
}
}

func TestCmdBanner_TopPadding(t *testing.T) {
b, err := NewCmdBanner([]string{"Test"}, WithPadding(2, 0), WithColors([]color.Color{ColorCyan}))
if err != nil {
t.Fatalf("NewCmdBanner() error = %v", err)
}
result, err := CmdBanner(b)
if err != nil {
t.Fatalf("CmdBanner() error = %v", err)
}
if !strings.HasPrefix(result, "\n\n") {
t.Errorf("expected 2 leading newlines from TopPadding=2, got: %q", result[:min(20, len(result))])
}
if strings.HasPrefix(result, "\n\n\n") {
t.Errorf("expected exactly 2 leading newlines from TopPadding=2, got 3")
}
}

func TestCmdBanner_BottomPadding(t *testing.T) {
b, err := NewCmdBanner([]string{"Test"}, WithPadding(0, 2), WithColors([]color.Color{ColorCyan}))
if err != nil {
t.Fatalf("NewCmdBanner() error = %v", err)
}
result, err := CmdBanner(b)
if err != nil {
t.Fatalf("CmdBanner() error = %v", err)
}
if !strings.HasSuffix(result, "\n\n\n") {
t.Errorf("expected 3 trailing newlines (renderer \\n + BottomPadding=2), got: %q", result[max(0, len(result)-20):])
}
}

func TestCmdBanner_NoPadding(t *testing.T) {
b, err := NewCmdBanner([]string{"Test"}, WithPadding(0, 0), WithColors([]color.Color{ColorCyan}))
if err != nil {
t.Fatalf("NewCmdBanner() error = %v", err)
}
result, err := CmdBanner(b)
if err != nil {
t.Fatalf("CmdBanner() error = %v", err)
}
if strings.HasPrefix(result, "\n") {
t.Errorf("expected no leading newline with TopPadding=0, got: %q", result[:min(20, len(result))])
}
}