add 'sprintf' vs. 'printf' | add simple coloring test
This commit is contained in:
parent
2b9e25fa39
commit
98c8af7a67
27
colors.go
27
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
|
||||
}
|
||||
|
|
18
printer.go
18
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue