diff --git a/tools/utils/style/api.go b/tools/utils/style/api.go new file mode 100644 index 000000000..42892bf22 --- /dev/null +++ b/tools/utils/style/api.go @@ -0,0 +1,30 @@ +// License: GPLv3 Copyright: 2022, Kovid Goyal, + +package style + +import ( + "fmt" + "strings" +) + +type Context struct { + AllowEscapeCodes bool +} + +func (self *Context) SprintFunc(spec string) func(args ...interface{}) string { + p := prefix_for_spec(spec) + s := suffix_for_spec(spec) + + return func(args ...interface{}) string { + body := fmt.Sprint(args...) + if !self.AllowEscapeCodes { + return body + } + b := strings.Builder{} + b.Grow(len(p) + len(body) + len(s)) + b.WriteString(p) + b.WriteString(body) + b.WriteString(s) + return b.String() + } +} diff --git a/tools/utils/style/wrapper.go b/tools/utils/style/wrapper.go index e4af08664..5477bf278 100644 --- a/tools/utils/style/wrapper.go +++ b/tools/utils/style/wrapper.go @@ -27,7 +27,7 @@ func (self bool_value) as_sgr(start, end string, prefix, suffix []string) ([]str start, end = end, start } prefix = append(prefix, start) - suffix = append(suffix, start) + suffix = append(suffix, end) } return prefix, suffix } @@ -89,7 +89,7 @@ func (self color_type) as_sgr(number_base int, prefix, suffix []string) ([]strin prefix = append(prefix, fmt.Sprintf("%d:5:%d", number_base+8, num)) } } else { - prefix = append(prefix, fmt.Sprintf("%d:2:%d", number_base+8, self.val.Red, self.val.Green, self.val.Blue)) + prefix = append(prefix, fmt.Sprintf("%d:2:%d:%d:%d", number_base+8, self.val.Red, self.val.Green, self.val.Blue)) } return prefix, suffix } @@ -230,7 +230,7 @@ func (self *underline_value) from_string(val string) bool { case "dashed": ans = dashed_underline } - if ans != nil_underline { + if ans == nil_underline { return false } self.is_set = true @@ -240,9 +240,9 @@ func (self *underline_value) from_string(val string) bool { func (self underline_value) as_sgr(prefix, suffix []string) ([]string, []string) { if self.is_set { - s, e := "0", "0" + s, e := "4:0", "4:0" if self.style != no_underline { - s = strconv.Itoa(int(self.style)) + s = "4:" + strconv.Itoa(int(self.style)) } prefix = append(prefix, s) suffix = append(suffix, e) @@ -352,18 +352,3 @@ func suffix_for_spec(spec string) string { } return sb.String() } - -func Styler(spec string) func(args ...interface{}) string { - p := prefix_for_spec(spec) - s := suffix_for_spec(spec) - - return func(args ...interface{}) string { - body := fmt.Sprint(args...) - b := strings.Builder{} - b.Grow(len(p) + len(body) + len(s)) - b.WriteString(p) - b.WriteString(body) - b.WriteString(s) - return b.String() - } -} diff --git a/tools/utils/style/wrapper_test.go b/tools/utils/style/wrapper_test.go new file mode 100644 index 000000000..1e14e7b57 --- /dev/null +++ b/tools/utils/style/wrapper_test.go @@ -0,0 +1,38 @@ +// License: GPLv3 Copyright: 2022, Kovid Goyal, + +package style + +import ( + "fmt" + "testing" +) + +var _ = fmt.Print + +func TestANSIStyleContext(t *testing.T) { + var ctx = Context{AllowEscapeCodes: false} + sprint := ctx.SprintFunc("bold") + if sprint("test") != "test" { + t.Fatal("AllowEscapeCodes=false not respected") + } + ctx.AllowEscapeCodes = true + if sprint("test") == "test" { + t.Fatal("AllowEscapeCodes=true not respected") + } +} + +func TestANSIStyleSprint(t *testing.T) { + var ctx = Context{AllowEscapeCodes: true} + + test := func(spec string, prefix string, suffix string) { + actual := ctx.SprintFunc(spec)(" ") + expected := prefix + " " + suffix + if actual != expected { + t.Fatalf("Formatting with spec: %s failed expected != actual: %#v != %#v", spec, expected, actual) + } + } + + test("bold", "\x1b[1m", "\x1b[22m") + test("bold fg=red u=curly", "\x1b[1;4:3;31m", "\x1b[22;4:0;39m") + +}