1// Package xtermcolor provides a palette for xterm colors, and conversion to that palette from anything implementing color.Color 2package xtermcolor 3 4import ( 5 "errors" 6 "image/color" 7 "strconv" 8) 9 10// Colors lists Xterm color codes vs. RGBA; values taken from https://gist.github.com/jasonm23/2868981 11// color.Palette is really []color.Color and provides .Convert() and .Index() 12var Colors = color.Palette{ 13 // Basic block 14 0: color.RGBA{0x00, 0x00, 0x00, 0xff}, 15 1: color.RGBA{0x80, 0x00, 0x00, 0xff}, 16 2: color.RGBA{0x00, 0x80, 0x00, 0xff}, 17 3: color.RGBA{0x80, 0x80, 0x00, 0xff}, 18 4: color.RGBA{0x00, 0x00, 0x80, 0xff}, 19 5: color.RGBA{0x80, 0x00, 0x80, 0xff}, 20 6: color.RGBA{0x00, 0x80, 0x80, 0xff}, 21 7: color.RGBA{0xc0, 0xc0, 0xc0, 0xff}, 22 8: color.RGBA{0x80, 0x80, 0x80, 0xff}, 23 9: color.RGBA{0xff, 0x00, 0x00, 0xff}, 24 10: color.RGBA{0x00, 0xff, 0x00, 0xff}, 25 11: color.RGBA{0xff, 0xff, 0x00, 0xff}, 26 12: color.RGBA{0x00, 0x00, 0xff, 0xff}, 27 13: color.RGBA{0xff, 0x00, 0xff, 0xff}, 28 14: color.RGBA{0x00, 0xff, 0xff, 0xff}, 29 15: color.RGBA{0xff, 0xff, 0xff, 0xff}, 30 31 // 6x6x6 cube block 32 16: color.RGBA{0x00, 0x00, 0x00, 0xff}, 33 17: color.RGBA{0x00, 0x00, 0x5f, 0xff}, 34 18: color.RGBA{0x00, 0x00, 0x87, 0xff}, 35 19: color.RGBA{0x00, 0x00, 0xaf, 0xff}, 36 20: color.RGBA{0x00, 0x00, 0xd7, 0xff}, 37 21: color.RGBA{0x00, 0x00, 0xff, 0xff}, 38 22: color.RGBA{0x00, 0x5f, 0x00, 0xff}, 39 23: color.RGBA{0x00, 0x5f, 0x5f, 0xff}, 40 24: color.RGBA{0x00, 0x5f, 0x87, 0xff}, 41 25: color.RGBA{0x00, 0x5f, 0xaf, 0xff}, 42 26: color.RGBA{0x00, 0x5f, 0xd7, 0xff}, 43 27: color.RGBA{0x00, 0x5f, 0xff, 0xff}, 44 28: color.RGBA{0x00, 0x87, 0x00, 0xff}, 45 29: color.RGBA{0x00, 0x87, 0x5f, 0xff}, 46 30: color.RGBA{0x00, 0x87, 0x87, 0xff}, 47 31: color.RGBA{0x00, 0x87, 0xaf, 0xff}, 48 32: color.RGBA{0x00, 0x87, 0xd7, 0xff}, 49 33: color.RGBA{0x00, 0x87, 0xff, 0xff}, 50 34: color.RGBA{0x00, 0xaf, 0x00, 0xff}, 51 35: color.RGBA{0x00, 0xaf, 0x5f, 0xff}, 52 36: color.RGBA{0x00, 0xaf, 0x87, 0xff}, 53 37: color.RGBA{0x00, 0xaf, 0xaf, 0xff}, 54 38: color.RGBA{0x00, 0xaf, 0xd7, 0xff}, 55 39: color.RGBA{0x00, 0xaf, 0xff, 0xff}, 56 40: color.RGBA{0x00, 0xd7, 0x00, 0xff}, 57 41: color.RGBA{0x00, 0xd7, 0x5f, 0xff}, 58 42: color.RGBA{0x00, 0xd7, 0x87, 0xff}, 59 43: color.RGBA{0x00, 0xd7, 0xaf, 0xff}, 60 44: color.RGBA{0x00, 0xd7, 0xd7, 0xff}, 61 45: color.RGBA{0x00, 0xd7, 0xff, 0xff}, 62 46: color.RGBA{0x00, 0xff, 0x00, 0xff}, 63 47: color.RGBA{0x00, 0xff, 0x5f, 0xff}, 64 48: color.RGBA{0x00, 0xff, 0x87, 0xff}, 65 49: color.RGBA{0x00, 0xff, 0xaf, 0xff}, 66 50: color.RGBA{0x00, 0xff, 0xd7, 0xff}, 67 51: color.RGBA{0x00, 0xff, 0xff, 0xff}, 68 82: color.RGBA{0x5f, 0xff, 0x00, 0xff}, 69 83: color.RGBA{0x5f, 0xff, 0x5f, 0xff}, 70 84: color.RGBA{0x5f, 0xff, 0x87, 0xff}, 71 85: color.RGBA{0x5f, 0xff, 0xaf, 0xff}, 72 86: color.RGBA{0x5f, 0xff, 0xd7, 0xff}, 73 87: color.RGBA{0x5f, 0xff, 0xff, 0xff}, 74 76: color.RGBA{0x5f, 0xd7, 0x00, 0xff}, 75 77: color.RGBA{0x5f, 0xd7, 0x5f, 0xff}, 76 78: color.RGBA{0x5f, 0xd7, 0x87, 0xff}, 77 79: color.RGBA{0x5f, 0xd7, 0xaf, 0xff}, 78 80: color.RGBA{0x5f, 0xd7, 0xd7, 0xff}, 79 81: color.RGBA{0x5f, 0xd7, 0xff, 0xff}, 80 70: color.RGBA{0x5f, 0xaf, 0x00, 0xff}, 81 71: color.RGBA{0x5f, 0xaf, 0x5f, 0xff}, 82 72: color.RGBA{0x5f, 0xaf, 0x87, 0xff}, 83 73: color.RGBA{0x5f, 0xaf, 0xaf, 0xff}, 84 74: color.RGBA{0x5f, 0xaf, 0xd7, 0xff}, 85 75: color.RGBA{0x5f, 0xaf, 0xff, 0xff}, 86 64: color.RGBA{0x5f, 0x87, 0x00, 0xff}, 87 65: color.RGBA{0x5f, 0x87, 0x5f, 0xff}, 88 66: color.RGBA{0x5f, 0x87, 0x87, 0xff}, 89 67: color.RGBA{0x5f, 0x87, 0xaf, 0xff}, 90 68: color.RGBA{0x5f, 0x87, 0xd7, 0xff}, 91 69: color.RGBA{0x5f, 0x87, 0xff, 0xff}, 92 58: color.RGBA{0x5f, 0x5f, 0x00, 0xff}, 93 59: color.RGBA{0x5f, 0x5f, 0x5f, 0xff}, 94 60: color.RGBA{0x5f, 0x5f, 0x87, 0xff}, 95 61: color.RGBA{0x5f, 0x5f, 0xaf, 0xff}, 96 62: color.RGBA{0x5f, 0x5f, 0xd7, 0xff}, 97 63: color.RGBA{0x5f, 0x5f, 0xff, 0xff}, 98 52: color.RGBA{0x5f, 0x00, 0x00, 0xff}, 99 53: color.RGBA{0x5f, 0x00, 0x5f, 0xff}, 100 54: color.RGBA{0x5f, 0x00, 0x87, 0xff}, 101 55: color.RGBA{0x5f, 0x00, 0xaf, 0xff}, 102 56: color.RGBA{0x5f, 0x00, 0xd7, 0xff}, 103 57: color.RGBA{0x5f, 0x00, 0xff, 0xff}, 104 93: color.RGBA{0x87, 0x00, 0xff, 0xff}, 105 92: color.RGBA{0x87, 0x00, 0xd7, 0xff}, 106 91: color.RGBA{0x87, 0x00, 0xaf, 0xff}, 107 90: color.RGBA{0x87, 0x00, 0x87, 0xff}, 108 89: color.RGBA{0x87, 0x00, 0x5f, 0xff}, 109 88: color.RGBA{0x87, 0x00, 0x00, 0xff}, 110 99: color.RGBA{0x87, 0x5f, 0xff, 0xff}, 111 98: color.RGBA{0x87, 0x5f, 0xd7, 0xff}, 112 97: color.RGBA{0x87, 0x5f, 0xaf, 0xff}, 113 96: color.RGBA{0x87, 0x5f, 0x87, 0xff}, 114 95: color.RGBA{0x87, 0x5f, 0x5f, 0xff}, 115 94: color.RGBA{0x87, 0x5f, 0x00, 0xff}, 116 105: color.RGBA{0x87, 0x87, 0xff, 0xff}, 117 104: color.RGBA{0x87, 0x87, 0xd7, 0xff}, 118 103: color.RGBA{0x87, 0x87, 0xaf, 0xff}, 119 102: color.RGBA{0x87, 0x87, 0x87, 0xff}, 120 101: color.RGBA{0x87, 0x87, 0x5f, 0xff}, 121 100: color.RGBA{0x87, 0x87, 0x00, 0xff}, 122 111: color.RGBA{0x87, 0xaf, 0xff, 0xff}, 123 110: color.RGBA{0x87, 0xaf, 0xd7, 0xff}, 124 109: color.RGBA{0x87, 0xaf, 0xaf, 0xff}, 125 108: color.RGBA{0x87, 0xaf, 0x87, 0xff}, 126 107: color.RGBA{0x87, 0xaf, 0x5f, 0xff}, 127 106: color.RGBA{0x87, 0xaf, 0x00, 0xff}, 128 117: color.RGBA{0x87, 0xd7, 0xff, 0xff}, 129 116: color.RGBA{0x87, 0xd7, 0xd7, 0xff}, 130 115: color.RGBA{0x87, 0xd7, 0xaf, 0xff}, 131 114: color.RGBA{0x87, 0xd7, 0x87, 0xff}, 132 113: color.RGBA{0x87, 0xd7, 0x5f, 0xff}, 133 112: color.RGBA{0x87, 0xd7, 0x00, 0xff}, 134 123: color.RGBA{0x87, 0xff, 0xff, 0xff}, 135 122: color.RGBA{0x87, 0xff, 0xd7, 0xff}, 136 121: color.RGBA{0x87, 0xff, 0xaf, 0xff}, 137 120: color.RGBA{0x87, 0xff, 0x87, 0xff}, 138 119: color.RGBA{0x87, 0xff, 0x5f, 0xff}, 139 118: color.RGBA{0x87, 0xff, 0x00, 0xff}, 140 159: color.RGBA{0xaf, 0xff, 0xff, 0xff}, 141 158: color.RGBA{0xaf, 0xff, 0xd7, 0xff}, 142 157: color.RGBA{0xaf, 0xff, 0xaf, 0xff}, 143 156: color.RGBA{0xaf, 0xff, 0x87, 0xff}, 144 155: color.RGBA{0xaf, 0xff, 0x5f, 0xff}, 145 154: color.RGBA{0xaf, 0xff, 0x00, 0xff}, 146 153: color.RGBA{0xaf, 0xd7, 0xff, 0xff}, 147 152: color.RGBA{0xaf, 0xd7, 0xd7, 0xff}, 148 151: color.RGBA{0xaf, 0xd7, 0xaf, 0xff}, 149 150: color.RGBA{0xaf, 0xd7, 0x87, 0xff}, 150 149: color.RGBA{0xaf, 0xd7, 0x5f, 0xff}, 151 148: color.RGBA{0xaf, 0xd7, 0x00, 0xff}, 152 147: color.RGBA{0xaf, 0xaf, 0xff, 0xff}, 153 146: color.RGBA{0xaf, 0xaf, 0xd7, 0xff}, 154 145: color.RGBA{0xaf, 0xaf, 0xaf, 0xff}, 155 144: color.RGBA{0xaf, 0xaf, 0x87, 0xff}, 156 143: color.RGBA{0xaf, 0xaf, 0x5f, 0xff}, 157 142: color.RGBA{0xaf, 0xaf, 0x00, 0xff}, 158 141: color.RGBA{0xaf, 0x87, 0xff, 0xff}, 159 140: color.RGBA{0xaf, 0x87, 0xd7, 0xff}, 160 139: color.RGBA{0xaf, 0x87, 0xaf, 0xff}, 161 138: color.RGBA{0xaf, 0x87, 0x87, 0xff}, 162 137: color.RGBA{0xaf, 0x87, 0x5f, 0xff}, 163 136: color.RGBA{0xaf, 0x87, 0x00, 0xff}, 164 135: color.RGBA{0xaf, 0x5f, 0xff, 0xff}, 165 134: color.RGBA{0xaf, 0x5f, 0xd7, 0xff}, 166 133: color.RGBA{0xaf, 0x5f, 0xaf, 0xff}, 167 132: color.RGBA{0xaf, 0x5f, 0x87, 0xff}, 168 131: color.RGBA{0xaf, 0x5f, 0x5f, 0xff}, 169 130: color.RGBA{0xaf, 0x5f, 0x00, 0xff}, 170 129: color.RGBA{0xaf, 0x00, 0xff, 0xff}, 171 128: color.RGBA{0xaf, 0x00, 0xd7, 0xff}, 172 127: color.RGBA{0xaf, 0x00, 0xaf, 0xff}, 173 126: color.RGBA{0xaf, 0x00, 0x87, 0xff}, 174 125: color.RGBA{0xaf, 0x00, 0x5f, 0xff}, 175 124: color.RGBA{0xaf, 0x00, 0x00, 0xff}, 176 160: color.RGBA{0xd7, 0x00, 0x00, 0xff}, 177 161: color.RGBA{0xd7, 0x00, 0x5f, 0xff}, 178 162: color.RGBA{0xd7, 0x00, 0x87, 0xff}, 179 163: color.RGBA{0xd7, 0x00, 0xaf, 0xff}, 180 164: color.RGBA{0xd7, 0x00, 0xd7, 0xff}, 181 165: color.RGBA{0xd7, 0x00, 0xff, 0xff}, 182 166: color.RGBA{0xd7, 0x5f, 0x00, 0xff}, 183 167: color.RGBA{0xd7, 0x5f, 0x5f, 0xff}, 184 168: color.RGBA{0xd7, 0x5f, 0x87, 0xff}, 185 169: color.RGBA{0xd7, 0x5f, 0xaf, 0xff}, 186 170: color.RGBA{0xd7, 0x5f, 0xd7, 0xff}, 187 171: color.RGBA{0xd7, 0x5f, 0xff, 0xff}, 188 172: color.RGBA{0xd7, 0x87, 0x00, 0xff}, 189 173: color.RGBA{0xd7, 0x87, 0x5f, 0xff}, 190 174: color.RGBA{0xd7, 0x87, 0x87, 0xff}, 191 175: color.RGBA{0xd7, 0x87, 0xaf, 0xff}, 192 176: color.RGBA{0xd7, 0x87, 0xd7, 0xff}, 193 177: color.RGBA{0xd7, 0x87, 0xff, 0xff}, 194 178: color.RGBA{0xdf, 0xaf, 0x00, 0xff}, 195 179: color.RGBA{0xdf, 0xaf, 0x5f, 0xff}, 196 180: color.RGBA{0xdf, 0xaf, 0x87, 0xff}, 197 181: color.RGBA{0xdf, 0xaf, 0xaf, 0xff}, 198 182: color.RGBA{0xdf, 0xaf, 0xdf, 0xff}, 199 183: color.RGBA{0xdf, 0xaf, 0xff, 0xff}, 200 184: color.RGBA{0xdf, 0xdf, 0x00, 0xff}, 201 185: color.RGBA{0xdf, 0xdf, 0x5f, 0xff}, 202 186: color.RGBA{0xdf, 0xdf, 0x87, 0xff}, 203 187: color.RGBA{0xdf, 0xdf, 0xaf, 0xff}, 204 188: color.RGBA{0xdf, 0xdf, 0xdf, 0xff}, 205 189: color.RGBA{0xdf, 0xdf, 0xff, 0xff}, 206 190: color.RGBA{0xdf, 0xff, 0x00, 0xff}, 207 191: color.RGBA{0xdf, 0xff, 0x5f, 0xff}, 208 192: color.RGBA{0xdf, 0xff, 0x87, 0xff}, 209 193: color.RGBA{0xdf, 0xff, 0xaf, 0xff}, 210 194: color.RGBA{0xdf, 0xff, 0xdf, 0xff}, 211 195: color.RGBA{0xdf, 0xff, 0xff, 0xff}, 212 226: color.RGBA{0xff, 0xff, 0x00, 0xff}, 213 227: color.RGBA{0xff, 0xff, 0x5f, 0xff}, 214 228: color.RGBA{0xff, 0xff, 0x87, 0xff}, 215 229: color.RGBA{0xff, 0xff, 0xaf, 0xff}, 216 230: color.RGBA{0xff, 0xff, 0xdf, 0xff}, 217 231: color.RGBA{0xff, 0xff, 0xff, 0xff}, 218 220: color.RGBA{0xff, 0xdf, 0x00, 0xff}, 219 221: color.RGBA{0xff, 0xdf, 0x5f, 0xff}, 220 222: color.RGBA{0xff, 0xdf, 0x87, 0xff}, 221 223: color.RGBA{0xff, 0xdf, 0xaf, 0xff}, 222 224: color.RGBA{0xff, 0xdf, 0xdf, 0xff}, 223 225: color.RGBA{0xff, 0xdf, 0xff, 0xff}, 224 214: color.RGBA{0xff, 0xaf, 0x00, 0xff}, 225 215: color.RGBA{0xff, 0xaf, 0x5f, 0xff}, 226 216: color.RGBA{0xff, 0xaf, 0x87, 0xff}, 227 217: color.RGBA{0xff, 0xaf, 0xaf, 0xff}, 228 218: color.RGBA{0xff, 0xaf, 0xdf, 0xff}, 229 219: color.RGBA{0xff, 0xaf, 0xff, 0xff}, 230 208: color.RGBA{0xff, 0x87, 0x00, 0xff}, 231 209: color.RGBA{0xff, 0x87, 0x5f, 0xff}, 232 210: color.RGBA{0xff, 0x87, 0x87, 0xff}, 233 211: color.RGBA{0xff, 0x87, 0xaf, 0xff}, 234 212: color.RGBA{0xff, 0x87, 0xdf, 0xff}, 235 213: color.RGBA{0xff, 0x87, 0xff, 0xff}, 236 202: color.RGBA{0xff, 0x5f, 0x00, 0xff}, 237 203: color.RGBA{0xff, 0x5f, 0x5f, 0xff}, 238 204: color.RGBA{0xff, 0x5f, 0x87, 0xff}, 239 205: color.RGBA{0xff, 0x5f, 0xaf, 0xff}, 240 206: color.RGBA{0xff, 0x5f, 0xdf, 0xff}, 241 207: color.RGBA{0xff, 0x5f, 0xff, 0xff}, 242 196: color.RGBA{0xff, 0x00, 0x00, 0xff}, 243 197: color.RGBA{0xff, 0x00, 0x5f, 0xff}, 244 198: color.RGBA{0xff, 0x00, 0x87, 0xff}, 245 199: color.RGBA{0xff, 0x00, 0xaf, 0xff}, 246 200: color.RGBA{0xff, 0x00, 0xdf, 0xff}, 247 201: color.RGBA{0xff, 0x00, 0xff, 0xff}, 248 249 // Grayscale block 250 232: color.RGBA{0x08, 0x08, 0x08, 0xff}, 251 233: color.RGBA{0x12, 0x12, 0x12, 0xff}, 252 234: color.RGBA{0x1c, 0x1c, 0x1c, 0xff}, 253 235: color.RGBA{0x26, 0x26, 0x26, 0xff}, 254 236: color.RGBA{0x30, 0x30, 0x30, 0xff}, 255 237: color.RGBA{0x3a, 0x3a, 0x3a, 0xff}, 256 238: color.RGBA{0x44, 0x44, 0x44, 0xff}, 257 239: color.RGBA{0x4e, 0x4e, 0x4e, 0xff}, 258 240: color.RGBA{0x58, 0x58, 0x58, 0xff}, 259 241: color.RGBA{0x62, 0x62, 0x62, 0xff}, 260 242: color.RGBA{0x6c, 0x6c, 0x6c, 0xff}, 261 243: color.RGBA{0x76, 0x76, 0x76, 0xff}, 262 255: color.RGBA{0xee, 0xee, 0xee, 0xff}, 263 254: color.RGBA{0xe4, 0xe4, 0xe4, 0xff}, 264 253: color.RGBA{0xda, 0xda, 0xda, 0xff}, 265 252: color.RGBA{0xd0, 0xd0, 0xd0, 0xff}, 266 251: color.RGBA{0xc6, 0xc6, 0xc6, 0xff}, 267 250: color.RGBA{0xbc, 0xbc, 0xbc, 0xff}, 268 249: color.RGBA{0xb2, 0xb2, 0xb2, 0xff}, 269 248: color.RGBA{0xa8, 0xa8, 0xa8, 0xff}, 270 247: color.RGBA{0x9e, 0x9e, 0x9e, 0xff}, 271 246: color.RGBA{0x94, 0x94, 0x94, 0xff}, 272 245: color.RGBA{0x8a, 0x8a, 0x8a, 0xff}, 273 244: color.RGBA{0x80, 0x80, 0x80, 0xff}, 274} 275 276var ( 277 // ErrorEmptyHexStr is returned by FromHexStr when an empty hex string is provided 278 ErrorEmptyHexStr = errors.New("Empty hex string provided") 279 280 // ErrorHexParse is returned by FromHexStr when an invalid hex string is provided 281 ErrorHexParse = errors.New("Failed to parse string as hex; try something like #CC66FF") 282) 283 284// Convert a 32 bit color to a color.RGBA 285func intToRGBA(c uint32) color.RGBA { 286 r := uint8((c >> 24) & 0xff) 287 g := uint8((c >> 16) & 0xff) 288 b := uint8((c >> 8) & 0xff) 289 a := uint8(c & 0xff) 290 return color.RGBA{r, g, b, a} 291} 292 293// FromColor finds the closest xterm colour to a given color.Color 294func FromColor(target color.Color) uint8 { 295 296 return uint8(Colors.Index(target)) 297} 298 299// FromInt finds the closest xterm color to a given 32 bit RGBA color (e.g. 0xff00ff00). 300func FromInt(target uint32) uint8 { 301 return FromColor(intToRGBA(target)) 302} 303 304// FromHexStr finds the closest xterm color to a given 24 bit hex string, e.g. "#CC66FF" or "FEFEFE" 305// It's mostly useful if you're used to specifying colours as hex in CSS etc 306func FromHexStr(str string) (uint8, error) { 307 if len(str) == 0 { 308 return 0, ErrorEmptyHexStr 309 } 310 311 if str[0] == '#' { 312 str = str[1:] 313 } 314 v, err := strconv.ParseUint(str, 16, 24) 315 if err != nil { 316 return 0, ErrorHexParse 317 } 318 return FromInt(uint32((v << 8) + 0xFF)), nil 319} 320