diff --git a/color.go b/color.go index a27f041..7609eeb 100644 --- a/color.go +++ b/color.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/lucasb-eyer/go-colorful" + "github.com/muesli/gamut/palette" ) var ( @@ -35,6 +36,10 @@ type ANSI256Color int // RGBColor is a hex-encoded color, e.g. "#abcdef". type RGBColor string +// CSSNamedColor is a color as defined by the CSS color standards, e.g. "red". +// Colors are supported through CSS Color Module Level 4. +type CSSNamedColor string + func ConvertToRGB(c Color) colorful.Color { var hex string switch v := c.(type) { @@ -91,6 +96,8 @@ func (p Profile) Color(s string) Color { var c Color if strings.HasPrefix(s, "#") { c = RGBColor(s) + } else if _, ok := palette.CSS.Color(s); ok { + c = CSSNamedColor(s) } else { i, err := strconv.Atoi(s) if err != nil { @@ -152,6 +159,21 @@ func (c RGBColor) Sequence(bg bool) string { return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255)) } +func (c CSSNamedColor) Sequence(bg bool) string { + f, ok := palette.CSS.Color(string(c)) + if !ok { + return "" + } + + r, g, b, _ := f.RGBA() + + prefix := Foreground + if bg { + prefix = Background + } + return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(r), uint8(g), uint8(b)) +} + func xTermColor(s string) (RGBColor, error) { if len(s) < 24 || len(s) > 25 { return RGBColor(""), ErrInvalidColor diff --git a/color_test.go b/color_test.go index de47355..aabb1a5 100644 --- a/color_test.go +++ b/color_test.go @@ -1,6 +1,8 @@ package termenv -import "testing" +import ( + "testing" +) func TestXTermColor(t *testing.T) { var tests = []struct { @@ -57,3 +59,26 @@ func TestXTermColor(t *testing.T) { }) } } + +func TestCSSNamedColor(t *testing.T) { + var tests = []struct { + name string + expected string + }{ + { + "red", + "38;2;255;0;0", + }, + { + "rebeccapurple", + "38;2;102;51;153", + }, + } + + for _, test := range tests { + res := CSSNamedColor(test.name).Sequence(false) + if res != test.expected { + t.Fatalf("wrong color returned, want %v, got %v", test.expected, res) + } + } +} diff --git a/go.mod b/go.mod index d29acd3..64f13f7 100644 --- a/go.mod +++ b/go.mod @@ -6,5 +6,6 @@ require ( github.com/lucasb-eyer/go-colorful v1.0.3 github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-runewidth v0.0.9 + github.com/muesli/gamut v0.1.3-0.20201204030319-712673bc0c9d golang.org/x/sys v0.0.0-20200116001909-b77594299b42 ) diff --git a/go.sum b/go.sum index 2ca034b..07cadd3 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,28 @@ +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/blend/go-sdk v2.0.0+incompatible h1:FL9X/of4ZYO5D2JJNI4vHrbXPfuSDbUa7h8JP9+E92w= +github.com/blend/go-sdk v2.0.0+incompatible/go.mod h1:3GUb0YsHFNTJ6hsJTpzdmCUl05o8HisKjx5OAlzYKdw= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/muesli/clusters v0.0.0-20180605185049-a07a36e67d36/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY= +github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762 h1:p4A2Jx7Lm3NV98VRMKlyWd3nqf8obft8NfXlAUmqd3I= +github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY= +github.com/muesli/gamut v0.1.3-0.20201204030319-712673bc0c9d h1:viLCvENFa2+h6CrVukUcje9+tb/3j5j58AA+R/l+m+c= +github.com/muesli/gamut v0.1.3-0.20201204030319-712673bc0c9d/go.mod h1:ItWqD/8gN+iyhkOJFN0COXkgeQjKNCOkA8KnojuYI1U= +github.com/muesli/kmeans v0.0.0-20200718051629-66f1657148c0 h1:xptegMPjfY9TDf49s3E5QFV1dZeA3acCq9IKTGirMLo= +github.com/muesli/kmeans v0.0.0-20200718051629-66f1657148c0/go.mod h1:+s8P1Egy3DkSU5+p4yBBn9SQQP1RhzZEgLw98DNYljQ= +github.com/wcharczuk/go-chart v2.0.2-0.20191206192251-962b9abdec2b+incompatible h1:ahpaSRefPekV3gcXot2AOgngIV8WYqzvDyFe3i7W24w= +github.com/wcharczuk/go-chart v2.0.2-0.20191206192251-962b9abdec2b+incompatible/go.mod h1:PF5tmL4EIx/7Wf+hEkpCqYi5He4u90sw+0+6FhrryuE= +github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b h1:tnWgqoOBmInkt5pbLjagwNVjjT4RdJhFHzL1ebCSRh8= +github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75 h1:TbGuee8sSq15Iguxu4deQ7+Bqq/d2rsQejGcEtADAMQ= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=