add 'sprintf' vs. 'printf' | add simple coloring test

This commit is contained in:
xdrm-brackets 2019-01-25 11:59:38 +01:00
parent 2b9e25fa39
commit 98c8af7a67
3 changed files with 120 additions and 10 deletions

View File

@ -8,20 +8,35 @@ import (
type terminalColor uint32 type terminalColor uint32
var colorMap = make(map[string]terminalColor) type Theme map[string]terminalColor
var theme Theme = make(map[string]terminalColor)
func init() { func init() {
colorMap["red"] = 0xff0000 theme["black"] = 0x000000
colorMap["green"] = 0x00ff00 theme["white"] = 0xffffff
colorMap["blue"] = 0x0000ff 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 // fromName returns the integer value of a color name
// from the built-in color map ; it is case insensitive // from the built-in color map ; it is case insensitive
func fromName(s string) (terminalColor, error) { func fromName(s string) (terminalColor, error) {
value, ok := colorMap[s] value, ok := theme[s]
if !ok { if !ok {
return 0, fmt.Errorf("unknown color name '%'", s) return 0, fmt.Errorf("unknown color name '%s'", s)
} }
return value, nil return value, nil
} }

View File

@ -16,7 +16,8 @@ import (
// - [Format] -> ${Text}(:Color) # background color only // - [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}))))?\)`) 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' // 1. Pre-process format with 'fmt'
input := fmt.Sprintf(format, a...) input := fmt.Sprintf(format, a...)
output := "" output := ""
@ -45,14 +46,14 @@ func Printf(format string, a ...interface{}) error {
sForeground = input[match[4]:match[5]] sForeground = input[match[4]:match[5]]
foreground, err = parseColor(sForeground) foreground, err = parseColor(sForeground)
if err != nil { if err != nil {
return err return "", err
} }
} }
if match[7]-match[6] > 0 { if match[7]-match[6] > 0 {
sBackground = input[match[6]:match[7]] sBackground = input[match[6]:match[7]]
background, err = parseColor(sBackground) background, err = parseColor(sBackground)
if err != nil { if err != nil {
return err return "", err
} }
} }
@ -72,7 +73,16 @@ func Printf(format string, a ...interface{}) error {
} }
// 3. print final output // 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 return nil
} }

85
printer_test.go Normal file
View File

@ -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)
}
}
}