1package color 2 3import ( 4 "fmt" 5 "strconv" 6 "strings" 7) 8 9/* 10from wikipedia, 256 color: 11 ESC[ … 38;5;<n> … m选择前景色 12 ESC[ … 48;5;<n> … m选择背景色 13 0- 7:标准颜色(同 ESC[30–37m) 14 8- 15:高强度颜色(同 ESC[90–97m) 15 16-231:6 × 6 × 6 立方(216色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5) 16 232-255:从黑到白的24阶灰度色 17*/ 18 19// tpl for 8 bit 256 color(`2^8`) 20// 21// format: 22// ESC[ … 38;5;<n> … m // 选择前景色 23// ESC[ … 48;5;<n> … m // 选择背景色 24// 25// example: 26// fg "\x1b[38;5;242m" 27// bg "\x1b[48;5;208m" 28// both "\x1b[38;5;242;48;5;208m" 29// 30// links: 31// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位 32const ( 33 TplFg256 = "38;5;%d" 34 TplBg256 = "48;5;%d" 35 Fg256Pfx = "38;5;" 36 Bg256Pfx = "48;5;" 37) 38 39/************************************************************* 40 * 8bit(256) Color: Bit8Color Color256 41 *************************************************************/ 42 43// Color256 256 color (8 bit), uint8 range at 0 - 255 44// 45// 颜色值使用10进制和16进制都可 0x98 = 152 46// 47// The color consists of two uint8: 48// 0: color value 49// 1: color type; Fg=0, Bg=1, >1: unset value 50// 51// example: 52// fg color: [152, 0] 53// bg color: [152, 1] 54// 55// NOTICE: now support 256 color on windows CMD, PowerShell 56// lint warn - Name starts with package name 57type Color256 [2]uint8 58type Bit8Color = Color256 // alias 59 60var emptyC256 = Color256{1: 99} 61 62// Bit8 create a color256 63func Bit8(val uint8, isBg ...bool) Color256 { 64 return C256(val, isBg...) 65} 66 67// C256 create a color256 68func C256(val uint8, isBg ...bool) Color256 { 69 bc := Color256{val} 70 71 // mark is bg color 72 if len(isBg) > 0 && isBg[0] { 73 bc[1] = AsBg 74 } 75 76 return bc 77} 78 79// Set terminal by 256 color code 80func (c Color256) Set() error { 81 return SetTerminal(c.String()) 82} 83 84// Reset terminal. alias of the ResetTerminal() 85func (c Color256) Reset() error { 86 return ResetTerminal() 87} 88 89// Print print message 90func (c Color256) Print(a ...interface{}) { 91 doPrintV2(c.String(), fmt.Sprint(a...)) 92} 93 94// Printf format and print message 95func (c Color256) Printf(format string, a ...interface{}) { 96 doPrintV2(c.String(), fmt.Sprintf(format, a...)) 97} 98 99// Println print message with newline 100func (c Color256) Println(a ...interface{}) { 101 doPrintlnV2(c.String(), a) 102} 103 104// Sprint returns rendered message 105func (c Color256) Sprint(a ...interface{}) string { 106 return RenderCode(c.String(), a...) 107} 108 109// Sprintf returns format and rendered message 110func (c Color256) Sprintf(format string, a ...interface{}) string { 111 return RenderString(c.String(), fmt.Sprintf(format, a...)) 112} 113 114// C16 convert color-256 to 16 color. 115func (c Color256) C16() Color { 116 return c.Basic() 117} 118 119// Basic convert color-256 to basic 16 color. 120func (c Color256) Basic() Color { 121 return Color(c[0]) // TODO 122} 123 124// RGB convert color-256 to RGB color. 125func (c Color256) RGB() RGBColor { 126 return RGBFromSlice(C256ToRgb(c[0]), c[1] == AsBg) 127} 128 129// RGBColor convert color-256 to RGB color. 130func (c Color256) RGBColor() RGBColor { 131 return c.RGB() 132} 133 134// Value return color value 135func (c Color256) Value() uint8 { 136 return c[0] 137} 138 139// Code convert to color code string. eg: "12" 140func (c Color256) Code() string { 141 return strconv.Itoa(int(c[0])) 142} 143 144// FullCode convert to color code string with prefix. eg: "38;5;12" 145func (c Color256) FullCode() string { 146 return c.String() 147} 148 149// String convert to color code string with prefix. eg: "38;5;12" 150func (c Color256) String() string { 151 if c[1] == AsFg { // 0 is Fg 152 // return fmt.Sprintf(TplFg256, c[0]) 153 return Fg256Pfx + strconv.Itoa(int(c[0])) 154 } 155 156 if c[1] == AsBg { // 1 is Bg 157 // return fmt.Sprintf(TplBg256, c[0]) 158 return Bg256Pfx + strconv.Itoa(int(c[0])) 159 } 160 161 return "" // empty 162} 163 164// IsFg color 165func (c Color256) IsFg() bool { 166 return c[1] == AsFg 167} 168 169// ToFg 256 color 170func (c Color256) ToFg() Color256 { 171 c[1] = AsFg 172 return c 173} 174 175// IsBg color 176func (c Color256) IsBg() bool { 177 return c[1] == AsBg 178} 179 180// ToBg 256 color 181func (c Color256) ToBg() Color256 { 182 c[1] = AsBg 183 return c 184} 185 186// IsEmpty value 187func (c Color256) IsEmpty() bool { 188 return c[1] > 1 189} 190 191/************************************************************* 192 * 8bit(256) Style 193 *************************************************************/ 194 195// Style256 definition 196// 197// 前/背景色 198// 都是由两位uint8组成, 第一位是色彩值; 199// 第二位与 Bit8Color 不一样的是,在这里表示是否设置了值 0 未设置 !=0 已设置 200type Style256 struct { 201 // p Printer 202 203 // Name of the style 204 Name string 205 // color options of the style 206 opts Opts 207 // fg and bg color 208 fg, bg Color256 209} 210 211// S256 create a color256 style 212// Usage: 213// s := color.S256() 214// s := color.S256(132) // fg 215// s := color.S256(132, 203) // fg and bg 216func S256(fgAndBg ...uint8) *Style256 { 217 s := &Style256{} 218 vl := len(fgAndBg) 219 if vl > 0 { // with fg 220 s.fg = Color256{fgAndBg[0], 1} 221 222 if vl > 1 { // and with bg 223 s.bg = Color256{fgAndBg[1], 1} 224 } 225 } 226 227 return s 228} 229 230// Set fg and bg color value, can also with color options 231func (s *Style256) Set(fgVal, bgVal uint8, opts ...Color) *Style256 { 232 s.fg = Color256{fgVal, 1} 233 s.bg = Color256{bgVal, 1} 234 s.opts.Add(opts...) 235 return s 236} 237 238// SetBg set bg color value 239func (s *Style256) SetBg(bgVal uint8) *Style256 { 240 s.bg = Color256{bgVal, 1} 241 return s 242} 243 244// SetFg set fg color value 245func (s *Style256) SetFg(fgVal uint8) *Style256 { 246 s.fg = Color256{fgVal, 1} 247 return s 248} 249 250// SetOpts set options 251func (s *Style256) SetOpts(opts Opts) *Style256 { 252 s.opts = opts 253 return s 254} 255 256// AddOpts add options 257func (s *Style256) AddOpts(opts ...Color) *Style256 { 258 s.opts.Add(opts...) 259 return s 260} 261 262// Print message 263func (s *Style256) Print(a ...interface{}) { 264 doPrintV2(s.String(), fmt.Sprint(a...)) 265} 266 267// Printf format and print message 268func (s *Style256) Printf(format string, a ...interface{}) { 269 doPrintV2(s.String(), fmt.Sprintf(format, a...)) 270} 271 272// Println print message with newline 273func (s *Style256) Println(a ...interface{}) { 274 doPrintlnV2(s.String(), a) 275} 276 277// Sprint returns rendered message 278func (s *Style256) Sprint(a ...interface{}) string { 279 return RenderCode(s.Code(), a...) 280} 281 282// Sprintf returns format and rendered message 283func (s *Style256) Sprintf(format string, a ...interface{}) string { 284 return RenderString(s.Code(), fmt.Sprintf(format, a...)) 285} 286 287// Code convert to color code string 288func (s *Style256) Code() string { 289 return s.String() 290} 291 292// String convert to color code string 293func (s *Style256) String() string { 294 var ss []string 295 if s.fg[1] > 0 { 296 ss = append(ss, fmt.Sprintf(TplFg256, s.fg[0])) 297 } 298 299 if s.bg[1] > 0 { 300 ss = append(ss, fmt.Sprintf(TplBg256, s.bg[0])) 301 } 302 303 if s.opts.IsValid() { 304 ss = append(ss, s.opts.String()) 305 } 306 307 return strings.Join(ss, ";") 308} 309