@@ -7,10 +7,9 @@ import (
77 "strings"
88)
99
10- // RGB is an RGB color
11- type RGB struct{ R, G, B uint8 }
10+ type rgb struct{ r, g, b uint8 }
1211
13- // Scale is a color scale
12+ // Scale is a color scale, a function mapping [0,1] to rgb colors.
1413type Scale func(float64) (r, g, b uint8)
1514
1615func index(r, g, b uint8) int {
@@ -33,32 +32,33 @@ func clamp(c float64) float64 {
3332var notHexChars = regexp.MustCompile("[^0-9a-fA-F]")
3433var spaces = regexp.MustCompile("\\s+")
3534
36- func parse3(s string, c *RGB ) {
35+ func parse3(s string, c *rgb ) {
3736 r, _ := strconv.ParseUint(s[0:1], 16, 8)
38- c.R = uint8((r << 4) | r)
37+ c.r = uint8((r << 4) | r)
3938 g, _ := strconv.ParseUint(s[1:2], 16, 8)
40- c.G = uint8((g << 4) | g)
39+ c.g = uint8((g << 4) | g)
4140 b, _ := strconv.ParseUint(s[2:3], 16, 8)
42- c.B = uint8((b << 4) | b)
41+ c.b = uint8((b << 4) | b)
4342}
4443
45- func parse6(s string, c *RGB ) {
44+ func parse6(s string, c *rgb ) {
4645 r, _ := strconv.ParseUint(s[0:2], 16, 8)
47- c.R = uint8(r)
46+ c.r = uint8(r)
4847 g, _ := strconv.ParseUint(s[2:4], 16, 8)
49- c.G = uint8(g)
48+ c.g = uint8(g)
5049 b, _ := strconv.ParseUint(s[4:6], 16, 8)
51- c.B = uint8(b)
50+ c.b = uint8(b)
5251}
5352
54- func Parse(scale string) []RGB {
53+ // ParseScale parses a sequence of hex colors as a Scale
54+ func ParseScale(scale string) Scale {
5555 hexOnly := notHexChars.ReplaceAllString(scale, " ")
5656 singleSpaced := spaces.ReplaceAllString(hexOnly, " ")
5757 trimmed := strings.TrimSpace(singleSpaced)
5858 lowercase := strings.ToLower(trimmed)
5959 parts := strings.Split(lowercase, " ")
6060
61- colors := make([]RGB , len(parts))
61+ colors := make([]rgb , len(parts))
6262 for i, s := range parts {
6363 switch len(s) {
6464 case 3:
@@ -67,18 +67,20 @@ func Parse(scale string) []RGB {
6767 parse6(s, &colors[i])
6868 }
6969 }
70- return colors
70+ return func(c float64) (r, g, b uint8) {
71+ return interpolate(c, colors)
72+ }
7173}
7274
73- func Interpolate2 (c float64, r1, g1, b1, r2, g2, b2 uint8) (r, g, b uint8) {
75+ func interpolate2 (c float64, r1, g1, b1, r2, g2, b2 uint8) (r, g, b uint8) {
7476 c = clamp(c)
7577 r = uint8(float64(r1)*(1-c) + float64(r2)*c)
7678 g = uint8(float64(g1)*(1-c) + float64(g2)*c)
7779 b = uint8(float64(b1)*(1-c) + float64(b2)*c)
7880 return
7981}
8082
81- func Interpolate (c float64, points []RGB ) (r, g, b uint8) {
83+ func interpolate (c float64, points []rgb ) (r, g, b uint8) {
8284 c = clamp(c)
8385 x := float64(len(points)-1) * c
8486 i := int(x)
@@ -89,13 +91,7 @@ func Interpolate(c float64, points []RGB) (r, g, b uint8) {
8991 }
9092 right := points[j]
9193 c = x - float64(i)
92- return Interpolate2(c, left.R, left.G, left.B, right.R, right.G, right.B)
93- }
94-
95- func NewScale(points []RGB) Scale {
96- return func(c float64) (r, g, b uint8) {
97- return Interpolate(c, points)
98- }
94+ return interpolate2(c, left.r, left.g, left.b, right.r, right.g, right.b)
9995}
10096
10197// Foreground returns the closest matching terminal foreground color escape sequence
0 commit comments