From 98c8af7a67691cdf4ad86736169e4e0cf1af7680 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Fri, 25 Jan 2019 11:59:38 +0100 Subject: [PATCH] add 'sprintf' vs. 'printf' | add simple coloring test --- colors.go | 27 ++++++++++++---- printer.go | 18 ++++++++--- printer_test.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 printer_test.go diff --git a/colors.go b/colors.go index 8595c2b..eca0f23 100644 --- a/colors.go +++ b/colors.go @@ -8,20 +8,35 @@ import ( type terminalColor uint32 -var colorMap = make(map[string]terminalColor) +type Theme map[string]terminalColor + +var theme Theme = make(map[string]terminalColor) func init() { - colorMap["red"] = 0xff0000 - colorMap["green"] = 0x00ff00 - colorMap["blue"] = 0x0000ff + theme["black"] = 0x000000 + theme["white"] = 0xffffff + theme["red"] = 0xff0000 + theme["green"] = 0x00ff00 + theme["blue"] = 0x0000ff + theme["yellow"] = 0xffff00 + theme["orange"] = 0xff8c00 + theme["purple"] = 0x800080 + theme["navy"] = 0x000080 + theme["aqua"] = 0x00ffff + theme["gray"] = 0x808080 + theme["silver"] = 0xc0c0c0 + theme["fuchsia"] = 0xff00ff + theme["olive"] = 0x808000 + theme["teal"] = 0x008080 + theme["brown"] = 0x800000 } // fromName returns the integer value of a color name // from the built-in color map ; it is case insensitive func fromName(s string) (terminalColor, error) { - value, ok := colorMap[s] + value, ok := theme[s] if !ok { - return 0, fmt.Errorf("unknown color name '%'", s) + return 0, fmt.Errorf("unknown color name '%s'", s) } return value, nil } diff --git a/printer.go b/printer.go index 137bdb5..95f25c4 100644 --- a/printer.go +++ b/printer.go @@ -16,7 +16,8 @@ import ( // - [Format] -> ${Text}(:Color) # background color only var extractor = regexp.MustCompile(`(?m)\${([^$]+)}\(((?:[a-z]+|#(?:[0-9a-f]{3}|[0-9a-f]{6})))?(?:\:((?:[a-z]+|#(?:[0-9a-f]{3}|[0-9a-f]{6}))))?\)`) -func Printf(format string, a ...interface{}) error { +// Sprintf returns a terminal-colorized output following the coloring format +func Sprintf(format string, a ...interface{}) (string, error) { // 1. Pre-process format with 'fmt' input := fmt.Sprintf(format, a...) output := "" @@ -45,14 +46,14 @@ func Printf(format string, a ...interface{}) error { sForeground = input[match[4]:match[5]] foreground, err = parseColor(sForeground) if err != nil { - return err + return "", err } } if match[7]-match[6] > 0 { sBackground = input[match[6]:match[7]] background, err = parseColor(sBackground) if err != nil { - return err + return "", err } } @@ -72,7 +73,16 @@ func Printf(format string, a ...interface{}) error { } // 3. print final output - fmt.Print(output) + return output, nil +} + +func Printf(format string, a ...interface{}) error { + s, err := Sprintf(format, a...) + if err != nil { + return err + } + + fmt.Print(s) return nil } diff --git a/printer_test.go b/printer_test.go new file mode 100644 index 0000000..a63e380 --- /dev/null +++ b/printer_test.go @@ -0,0 +1,85 @@ +package clifmt + +import ( + "testing" +) + +func TestColoring(t *testing.T) { + + tests := []struct { + Input string + Output string + }{ + // foreground + background + { + "start ${some text input}(#ff0000:#00ff00) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, { + "start ${some text input}(#f00:#0f0) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, { + "start ${some text input}(red:green) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, + + // mixed notations + { + "start ${some text input}(red:#00ff00) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, { + "start ${some text input}(red:#0f0) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, { + "start ${some text input}(#ff0000:green) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, { + "start ${some text input}(#f00:green) end\n", + "start \033[48;2;0;255;0m\033[38;2;255;0;0msome text input\033[0m\033[0m end\n", + }, + + // foreground only + { + "start ${some text input}(red) end\n", + "start \033[38;2;255;0;0msome text input\033[0m end\n", + }, { + "start ${some text input}(#ff0000) end\n", + "start \033[38;2;255;0;0msome text input\033[0m end\n", + }, { + "start ${some text input}(#f00) end\n", + "start \033[38;2;255;0;0msome text input\033[0m end\n", + }, + + // background only + { + "start ${some text input}(:blue) end\n", + "start \033[48;2;0;0;255msome text input\033[0m end\n", + }, { + "start ${some text input}(:#0000ff) end\n", + "start \033[48;2;0;0;255msome text input\033[0m end\n", + }, { + "start ${some text input}(:#00f) end\n", + "start \033[48;2;0;0;255msome text input\033[0m end\n", + }, + + // multi matches + { + "start ${text1}(red) separation ${text2}(#0f0) end\n", + "start \033[38;2;255;0;0mtext1\033[0m separation \033[38;2;0;255;0mtext2\033[0m end\n", + }, { + "start ${text1}(:red) separation ${text2}(:#0f0) end\n", + "start \033[48;2;255;0;0mtext1\033[0m separation \033[48;2;0;255;0mtext2\033[0m end\n", + }} + + for i, test := range tests { + output, err := Sprintf(test.Input) + if err != nil { + t.Errorf("[%d] unexpected error <%v>", i, err) + break + } + + if output != test.Output { + t.Errorf("[%d] expected '%s', got '%s'", i, test.Output, output) + } + + } +}