diff --git a/README.md b/README.md
index 23abd47..bbf6a26 100644
--- a/README.md
+++ b/README.md
@@ -109,7 +109,7 @@ cfmt.Println("{{%s}}::flag ", flag)
### HEX colors
-If the standard colors are not enough for you, then you can use the colors in the Hex format (note, not all consoles support all colors fully!).
+If the standard colors are not enough for you, then you can use the colors in the `HEX` format (note, not all terminals support all colors fully!).
```go
cfmt.Println("This is a {{red color}}::#ff0000")
@@ -123,7 +123,7 @@ To set the background color, you need to add the prefix `bg` to the color, in th
cfmt.Println("This is a {{red color}}::bgRed")
```
-For HEX it will look like this:
+For `HEX` it will look like this:
```go
cfmt.Println("This is a {{red color}}::bg#ff0000")
@@ -178,16 +178,15 @@ cfmt.Print(`
## Supported colors and styles
-| Styles |
-| ------------------------------------------------------ |
-| *italic* |
-| **bold** |
-| ~~crossout~~ |
-| underline |
-| overline |
-|faint|
-|reverse|
-|blink|
+| Styles |
+| -------------------- |
+| *italic* |
+| **bold** |
+| ~~crossout~~ |
+| underline |
+| concealed |
+| reverse |
+| blink |
| Colors | | | |
@@ -206,7 +205,7 @@ And colors in HEX format. See [HEX colors](#hex-colors) part.
## Motivation
-The existing libraries for styling output are very powerful, and this library is built on two of them (gookit/color and muesli/termenv). However, they are not very convenient to use for styling specific words or sentences, since you need to use `Sprintf` and put the stylized into a format string, which greatly reduces readability if you need to style many elements.
+The existing libraries for styling the output are very powerful and this library builds on one of them ([gookit / color] (https://github.com/gookit/color)). However, they are not very useful for styling certain words or sentences, since you need to use `Sprintf` and put the styled ones in a format string, which greatly reduces readability if you need to style many elements.
I believe that the library will be useful primarily for formatting ready-made text, for reference or examples. However, in other cases it should be just as convenient.
diff --git a/go.mod b/go.mod
index 917d01f..21b731d 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,5 @@ module github.com/i582/cfmt
go 1.15
require (
- github.com/google/go-cmp v0.5.3
github.com/gookit/color v1.3.2
- github.com/muesli/termenv v0.7.4
)
diff --git a/internal/bench/bench_test.go b/internal/bench/bench_test.go
deleted file mode 100644
index 737a6ad..0000000
--- a/internal/bench/bench_test.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package bench
-
-import (
- "testing"
-
- "github.com/i582/cfmt"
-)
-
-func TestParse(t *testing.T) {
- cfmt.Println("{{some}}::faint")
-}
diff --git a/internal/map.go b/internal/map.go
index e1eb0a3..188f8d1 100644
--- a/internal/map.go
+++ b/internal/map.go
@@ -5,12 +5,7 @@ import (
)
// CustomMap is the custom styles map
-var CustomMap = map[string]func(string) string{
- "overline": overline,
- "faint": faint,
- "reverse": reverse,
- "blink": blink,
-}
+var CustomMap = map[string]func(string) string{}
// Map is the styles map
var Map = map[string]color.Color{
@@ -54,4 +49,7 @@ var Map = map[string]color.Color{
"italic": color.OpItalic,
"crossout": color.OpStrikethrough,
"underline": color.OpUnderscore,
+ "blink": color.OpBlink,
+ "reverse": color.OpReverse,
+ "concealed": color.OpConcealed,
}
diff --git a/internal/parser.go b/internal/parser.go
index eae9310..81777bf 100644
--- a/internal/parser.go
+++ b/internal/parser.go
@@ -5,8 +5,8 @@ import (
"strings"
)
-// Parse parses the passed format string and applies styles, returning a styled string.
-func Parse(text string) string {
+// ParseAndApply parses the passed format string and applies styles, returning a styled string.
+func ParseAndApply(text string) string {
var resParts = make([]string, 0, 50)
var err error
@@ -149,9 +149,9 @@ func Parse(text string) string {
// text from :: or previous | to current |
singleFormat := text[tempTokenStartIndex:tempTokenEndIndex]
- lastToken, err = ApplyStyle(lastToken, singleFormat)
+ lastToken, err = applyStyle(lastToken, singleFormat)
if err != nil {
- log.Fatalf("Error parse style string in '%s' text string: %v", text, err)
+ log.Fatalf("Error parse style string in '%s' text string: %v", strings.ReplaceAll(text, "\n", "\\n"), err)
}
// index after |
@@ -164,9 +164,9 @@ func Parse(text string) string {
// last format
singleFormat := text[tempTokenStartIndex:tempTokenEndIndex]
- lastToken, err = ApplyStyle(lastToken, singleFormat)
+ lastToken, err = applyStyle(lastToken, singleFormat)
if err != nil {
- log.Fatalf("Error parse style string in '%s' text string: %v", text, err)
+ log.Fatalf("Error parse style string in '%s' text string: %v", strings.ReplaceAll(text, "\n", "\\n"), err)
}
tempTokenStartIndex = index
@@ -192,9 +192,9 @@ func Parse(text string) string {
if lastIsFormatGroup {
singleFormat := text[tempTokenStartIndex:]
- lastToken, err = ApplyStyle(lastToken, singleFormat)
+ lastToken, err = applyStyle(lastToken, singleFormat)
if err != nil {
- log.Fatalf("Error parse style string in '%s' text string: %v", text, err)
+ log.Fatalf("Error parse style string in '%s' text string: %v", strings.ReplaceAll(text, "\n", "\\n"), err)
}
resParts = append(resParts, lastToken)
} else {
diff --git a/internal/style.go b/internal/style.go
index 236a88f..37bcc6c 100644
--- a/internal/style.go
+++ b/internal/style.go
@@ -3,6 +3,8 @@ package internal
import (
"fmt"
"strings"
+
+ "github.com/gookit/color"
)
// StyleBuilder is a function that returns a styled string based on the supplied style.
@@ -13,7 +15,7 @@ func StyleBuilder(styles []string, text string) (string, error) {
var err error
for _, style := range styles {
- text, err = ApplyStyle(text, style)
+ text, err = applyStyle(text, style)
if err != nil {
return "", err
}
@@ -22,14 +24,14 @@ func StyleBuilder(styles []string, text string) (string, error) {
return text, nil
}
-// StyleBuilder is a function that apply a style for string.
-func ApplyStyle(text, style string) (string, error) {
+// applyStyle is a function that apply a style for string.
+func applyStyle(text, style string) (string, error) {
if isHex(style) {
err := checkHex(style)
if err != nil {
return "", err
}
- text = hexForegroundColorFunc(style, text)
+ text = hexForegroundColor(style, text)
return text, nil
}
@@ -39,7 +41,7 @@ func ApplyStyle(text, style string) (string, error) {
if err != nil {
return "", err
}
- text = hexBackgroundColorFunc(rawHex, text)
+ text = hexBackgroundColor(rawHex, text)
return text, nil
}
@@ -47,7 +49,7 @@ func ApplyStyle(text, style string) (string, error) {
if !ok {
customStyleFunc, ok := CustomMap[style]
if !ok {
- return "", fmt.Errorf("unknown style %s", style)
+ return "", fmt.Errorf("unknown style '%s'", style)
}
text = customStyleFunc(text)
return text, nil
@@ -56,17 +58,27 @@ func ApplyStyle(text, style string) (string, error) {
return clr.Sprint(text), nil
}
+func hexBackgroundColor(cl string, text string) string {
+ return color.HEX(cl, true).Sprint(text)
+}
+
+func hexForegroundColor(cl string, text string) string {
+ return color.HEX(cl).Sprint(text)
+}
+
func isHex(val string) bool {
return strings.HasPrefix(val, "#")
}
+func isBackgroundHex(val string) bool {
+ return strings.HasPrefix(val, "bg#")
+}
+
func checkHex(val string) error {
- if len(val) != 7 {
- return fmt.Errorf("invalid hex: length of hex color must be 6")
+ rgb := color.HexToRGB(val)
+ if len(rgb) > 0 {
+ return nil
}
- return nil
-}
-func isBackgroundHex(val string) bool {
- return strings.HasPrefix(val, "bg#")
+ return fmt.Errorf("invalid '%s' hex color", val)
}
diff --git a/internal/styles.go b/internal/styles.go
deleted file mode 100644
index 4a4842d..0000000
--- a/internal/styles.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package internal
-
-import (
- "github.com/muesli/termenv"
-)
-
-var colorProfile termenv.Profile
-
-func init() {
- colorProfile = termenv.ColorProfile()
-}
-
-func overline(text string) string {
- out := termenv.String(text)
- out = out.Overline()
- return out.String()
-}
-
-func reverse(text string) string {
- out := termenv.String(text)
- out = out.Reverse()
- return out.String()
-}
-
-func blink(text string) string {
- out := termenv.String(text)
- out = out.Blink()
- return out.String()
-}
-
-func faint(text string) string {
- out := termenv.String(text)
- out = out.Faint()
- return out.String()
-}
-
-func hexBackgroundColorFunc(cl string, text string) string {
- out := termenv.String(text)
- out = out.Background(colorProfile.Color(cl))
- return out.String()
-}
-
-func hexForegroundColorFunc(cl string, text string) string {
- out := termenv.String(text)
- out = out.Foreground(colorProfile.Color(cl))
- return out.String()
-}
diff --git a/main.go b/main.go
index fd9cdcd..6da40e9 100644
--- a/main.go
+++ b/main.go
@@ -25,8 +25,7 @@ func RegisterStyle(name string, fn func(string) string) {
// Sprint is the same as fmt.
func Sprint(a ...interface{}) string {
text := fmt.Sprint(a...)
- parsed := internal.Parse(text)
- return parsed
+ return internal.ParseAndApply(text)
}
// Fprint is the same as fmt.
@@ -59,8 +58,7 @@ func Println(a ...interface{}) (n int, err error) {
// Sprintf is the same as fmt.
func Sprintf(format string, a ...interface{}) string {
text := fmt.Sprintf(format, a...)
- parsed := internal.Parse(text)
- return parsed
+ return internal.ParseAndApply(text)
}
// Fprintf is the same as fmt.
@@ -76,12 +74,18 @@ func Printf(format string, a ...interface{}) (n int, err error) {
// Fatalf is the same as fmt.
func Fatalf(format string, a ...interface{}) {
- Printf(format, a...)
+ _, _ = Printf(format, a...)
os.Exit(1)
}
// Fatal is the same as fmt.
func Fatal(a ...interface{}) {
- Print(a...)
+ _, _ = Print(a...)
+ os.Exit(1)
+}
+
+// Fatalln is the same as fmt.
+func Fatalln(a ...interface{}) {
+ _, _ = Println(a...)
os.Exit(1)
}
diff --git a/tests/parser_test.go b/tests/parser_test.go
index 90670f0..e5cb7b2 100644
--- a/tests/parser_test.go
+++ b/tests/parser_test.go
@@ -25,11 +25,12 @@ func TestParse(t *testing.T) {
cfmt.Println("{{こんにちは, correct group}}::code sdas")
cfmt.Println("{{привет, correct group}}::red|underline and {{other}}::red")
cfmt.Print("{{error group}} \n")
- cfmt.Print("{{overline group}}::overline\n")
+ cfmt.Print("{{underline group}}::underline\n")
cfmt.Print("{{reverse group, こんにちは}}::reverse\n")
- cfmt.Print(cfmt.Sprintln("{{faint group}}::faint sfafs"))
+ cfmt.Print(cfmt.Sprintln("{{some group}}::red sfafs"))
cfmt.Println(cfmt.Sprint("{{blink group}}::blink"))
cfmt.Printf("{{hex %s}}::#ff00ff sfas\n", "color group")
+ cfmt.Printf("{{3 hex %s}}::#ff0 sfas\n", "color group")
cfmt.Printf(cfmt.Sprintf("{{background color %s}}::bg#ffff00\n", "hex color"))
cfmt.Printf("{{{hello}}}::red|underline\n")
cfmt.Printf("{{some test struct: %v}}::red|underline\n", TestStruct{"hello", 1})
diff --git a/tests/style_test.go b/tests/style_test.go
index 35d4e47..a5d69a1 100644
--- a/tests/style_test.go
+++ b/tests/style_test.go
@@ -3,8 +3,6 @@ package tests
import (
"testing"
- "github.com/google/go-cmp/cmp"
-
"github.com/i582/cfmt"
"github.com/i582/cfmt/internal"
)
@@ -41,20 +39,28 @@ func TestStyleBuilder(t *testing.T) {
Error: "",
},
{
- Value: []string{"overline", "reverse", "faint"},
+ Value: []string{"underline", "reverse"},
Error: "",
},
{
Value: []string{"bg#ff0", "bold"},
- Error: "invalid hex: length of hex color must be 6",
+ Error: "",
},
{
Value: []string{"#ff0", "bold"},
- Error: "invalid hex: length of hex color must be 6",
+ Error: "",
+ },
+ {
+ Value: []string{"#ff01", "bold"},
+ Error: "invalid '#ff01' hex color",
+ },
+ {
+ Value: []string{"bg#ff01", "bold"},
+ Error: "invalid '#ff01' hex color",
},
{
Value: []string{"some", "bold"},
- Error: "unknown style some",
+ Error: "unknown style 'some'",
},
{
Value: []string{},
@@ -65,12 +71,12 @@ func TestStyleBuilder(t *testing.T) {
for _, suite := range suites {
_, err := internal.StyleBuilder(suite.Value, "")
if err == nil && suite.Error != "" {
- t.Error(cmp.Diff("", suite.Error))
+ t.Errorf("mismatch\nwant: ''\nhave: %s", suite.Error)
continue
}
- if err != nil && !cmp.Equal(err.Error(), suite.Error) {
- t.Error(cmp.Diff(err.Error(), suite.Error))
+ if err != nil && err.Error() != suite.Error {
+ t.Errorf("mismatch\nwant: %s\nhave: %s", suite.Error, err.Error())
}
}
}