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
|
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
|
||||||
}
|
}
|
||||||
|
|
18
printer.go
18
printer.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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