309 lines
6.6 KiB
Go
309 lines
6.6 KiB
Go
|
package color
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"strconv"
|
|||
|
"strings"
|
|||
|
)
|
|||
|
|
|||
|
/*
|
|||
|
from wikipedia, 256 color:
|
|||
|
ESC[ … 38;5;<n> … m选择前景色
|
|||
|
ESC[ … 48;5;<n> … m选择背景色
|
|||
|
0- 7:标准颜色(同 ESC[30–37m)
|
|||
|
8- 15:高强度颜色(同 ESC[90–97m)
|
|||
|
16-231:6 × 6 × 6 立方(216色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
|
|||
|
232-255:从黑到白的24阶灰度色
|
|||
|
*/
|
|||
|
|
|||
|
// tpl for 8 bit 256 color(`2^8`)
|
|||
|
//
|
|||
|
// format:
|
|||
|
// ESC[ … 38;5;<n> … m // 选择前景色
|
|||
|
// ESC[ … 48;5;<n> … m // 选择背景色
|
|||
|
//
|
|||
|
// example:
|
|||
|
// fg "\x1b[38;5;242m"
|
|||
|
// bg "\x1b[48;5;208m"
|
|||
|
// both "\x1b[38;5;242;48;5;208m"
|
|||
|
//
|
|||
|
// links:
|
|||
|
// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位
|
|||
|
const (
|
|||
|
TplFg256 = "38;5;%d"
|
|||
|
TplBg256 = "48;5;%d"
|
|||
|
Fg256Pfx = "38;5;"
|
|||
|
Bg256Pfx = "48;5;"
|
|||
|
)
|
|||
|
|
|||
|
/*************************************************************
|
|||
|
* 8bit(256) Color: Bit8Color Color256
|
|||
|
*************************************************************/
|
|||
|
|
|||
|
// Color256 256 color (8 bit), uint8 range at 0 - 255
|
|||
|
//
|
|||
|
// 颜色值使用10进制和16进制都可 0x98 = 152
|
|||
|
//
|
|||
|
// The color consists of two uint8:
|
|||
|
// 0: color value
|
|||
|
// 1: color type; Fg=0, Bg=1, >1: unset value
|
|||
|
//
|
|||
|
// example:
|
|||
|
// fg color: [152, 0]
|
|||
|
// bg color: [152, 1]
|
|||
|
//
|
|||
|
// NOTICE: now support 256 color on windows CMD, PowerShell
|
|||
|
// lint warn - Name starts with package name
|
|||
|
type Color256 [2]uint8
|
|||
|
type Bit8Color = Color256 // alias
|
|||
|
|
|||
|
var emptyC256 = Color256{1: 99}
|
|||
|
|
|||
|
// Bit8 create a color256
|
|||
|
func Bit8(val uint8, isBg ...bool) Color256 {
|
|||
|
return C256(val, isBg...)
|
|||
|
}
|
|||
|
|
|||
|
// C256 create a color256
|
|||
|
func C256(val uint8, isBg ...bool) Color256 {
|
|||
|
bc := Color256{val}
|
|||
|
|
|||
|
// mark is bg color
|
|||
|
if len(isBg) > 0 && isBg[0] {
|
|||
|
bc[1] = AsBg
|
|||
|
}
|
|||
|
|
|||
|
return bc
|
|||
|
}
|
|||
|
|
|||
|
// Set terminal by 256 color code
|
|||
|
func (c Color256) Set() error {
|
|||
|
return SetTerminal(c.String())
|
|||
|
}
|
|||
|
|
|||
|
// Reset terminal. alias of the ResetTerminal()
|
|||
|
func (c Color256) Reset() error {
|
|||
|
return ResetTerminal()
|
|||
|
}
|
|||
|
|
|||
|
// Print print message
|
|||
|
func (c Color256) Print(a ...interface{}) {
|
|||
|
doPrintV2(c.String(), fmt.Sprint(a...))
|
|||
|
}
|
|||
|
|
|||
|
// Printf format and print message
|
|||
|
func (c Color256) Printf(format string, a ...interface{}) {
|
|||
|
doPrintV2(c.String(), fmt.Sprintf(format, a...))
|
|||
|
}
|
|||
|
|
|||
|
// Println print message with newline
|
|||
|
func (c Color256) Println(a ...interface{}) {
|
|||
|
doPrintlnV2(c.String(), a)
|
|||
|
}
|
|||
|
|
|||
|
// Sprint returns rendered message
|
|||
|
func (c Color256) Sprint(a ...interface{}) string {
|
|||
|
return RenderCode(c.String(), a...)
|
|||
|
}
|
|||
|
|
|||
|
// Sprintf returns format and rendered message
|
|||
|
func (c Color256) Sprintf(format string, a ...interface{}) string {
|
|||
|
return RenderString(c.String(), fmt.Sprintf(format, a...))
|
|||
|
}
|
|||
|
|
|||
|
// C16 convert color-256 to 16 color.
|
|||
|
func (c Color256) C16() Color {
|
|||
|
return c.Basic()
|
|||
|
}
|
|||
|
|
|||
|
// Basic convert color-256 to basic 16 color.
|
|||
|
func (c Color256) Basic() Color {
|
|||
|
return Color(c[0]) // TODO
|
|||
|
}
|
|||
|
|
|||
|
// RGB convert color-256 to RGB color.
|
|||
|
func (c Color256) RGB() RGBColor {
|
|||
|
return RGBFromSlice(C256ToRgb(c[0]), c[1] == AsBg)
|
|||
|
}
|
|||
|
|
|||
|
// RGBColor convert color-256 to RGB color.
|
|||
|
func (c Color256) RGBColor() RGBColor {
|
|||
|
return c.RGB()
|
|||
|
}
|
|||
|
|
|||
|
// Value return color value
|
|||
|
func (c Color256) Value() uint8 {
|
|||
|
return c[0]
|
|||
|
}
|
|||
|
|
|||
|
// Code convert to color code string. eg: "12"
|
|||
|
func (c Color256) Code() string {
|
|||
|
return strconv.Itoa(int(c[0]))
|
|||
|
}
|
|||
|
|
|||
|
// FullCode convert to color code string with prefix. eg: "38;5;12"
|
|||
|
func (c Color256) FullCode() string {
|
|||
|
return c.String()
|
|||
|
}
|
|||
|
|
|||
|
// String convert to color code string with prefix. eg: "38;5;12"
|
|||
|
func (c Color256) String() string {
|
|||
|
if c[1] == AsFg { // 0 is Fg
|
|||
|
// return fmt.Sprintf(TplFg256, c[0])
|
|||
|
return Fg256Pfx + strconv.Itoa(int(c[0]))
|
|||
|
}
|
|||
|
|
|||
|
if c[1] == AsBg { // 1 is Bg
|
|||
|
// return fmt.Sprintf(TplBg256, c[0])
|
|||
|
return Bg256Pfx + strconv.Itoa(int(c[0]))
|
|||
|
}
|
|||
|
|
|||
|
return "" // empty
|
|||
|
}
|
|||
|
|
|||
|
// IsFg color
|
|||
|
func (c Color256) IsFg() bool {
|
|||
|
return c[1] == AsFg
|
|||
|
}
|
|||
|
|
|||
|
// ToFg 256 color
|
|||
|
func (c Color256) ToFg() Color256 {
|
|||
|
c[1] = AsFg
|
|||
|
return c
|
|||
|
}
|
|||
|
|
|||
|
// IsBg color
|
|||
|
func (c Color256) IsBg() bool {
|
|||
|
return c[1] == AsBg
|
|||
|
}
|
|||
|
|
|||
|
// ToBg 256 color
|
|||
|
func (c Color256) ToBg() Color256 {
|
|||
|
c[1] = AsBg
|
|||
|
return c
|
|||
|
}
|
|||
|
|
|||
|
// IsEmpty value
|
|||
|
func (c Color256) IsEmpty() bool {
|
|||
|
return c[1] > 1
|
|||
|
}
|
|||
|
|
|||
|
/*************************************************************
|
|||
|
* 8bit(256) Style
|
|||
|
*************************************************************/
|
|||
|
|
|||
|
// Style256 definition
|
|||
|
//
|
|||
|
// 前/背景色
|
|||
|
// 都是由两位uint8组成, 第一位是色彩值;
|
|||
|
// 第二位与 Bit8Color 不一样的是,在这里表示是否设置了值 0 未设置 !=0 已设置
|
|||
|
type Style256 struct {
|
|||
|
// p Printer
|
|||
|
|
|||
|
// Name of the style
|
|||
|
Name string
|
|||
|
// color options of the style
|
|||
|
opts Opts
|
|||
|
// fg and bg color
|
|||
|
fg, bg Color256
|
|||
|
}
|
|||
|
|
|||
|
// S256 create a color256 style
|
|||
|
// Usage:
|
|||
|
// s := color.S256()
|
|||
|
// s := color.S256(132) // fg
|
|||
|
// s := color.S256(132, 203) // fg and bg
|
|||
|
func S256(fgAndBg ...uint8) *Style256 {
|
|||
|
s := &Style256{}
|
|||
|
vl := len(fgAndBg)
|
|||
|
if vl > 0 { // with fg
|
|||
|
s.fg = Color256{fgAndBg[0], 1}
|
|||
|
|
|||
|
if vl > 1 { // and with bg
|
|||
|
s.bg = Color256{fgAndBg[1], 1}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// Set fg and bg color value, can also with color options
|
|||
|
func (s *Style256) Set(fgVal, bgVal uint8, opts ...Color) *Style256 {
|
|||
|
s.fg = Color256{fgVal, 1}
|
|||
|
s.bg = Color256{bgVal, 1}
|
|||
|
s.opts.Add(opts...)
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// SetBg set bg color value
|
|||
|
func (s *Style256) SetBg(bgVal uint8) *Style256 {
|
|||
|
s.bg = Color256{bgVal, 1}
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// SetFg set fg color value
|
|||
|
func (s *Style256) SetFg(fgVal uint8) *Style256 {
|
|||
|
s.fg = Color256{fgVal, 1}
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// SetOpts set options
|
|||
|
func (s *Style256) SetOpts(opts Opts) *Style256 {
|
|||
|
s.opts = opts
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// AddOpts add options
|
|||
|
func (s *Style256) AddOpts(opts ...Color) *Style256 {
|
|||
|
s.opts.Add(opts...)
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// Print message
|
|||
|
func (s *Style256) Print(a ...interface{}) {
|
|||
|
doPrintV2(s.String(), fmt.Sprint(a...))
|
|||
|
}
|
|||
|
|
|||
|
// Printf format and print message
|
|||
|
func (s *Style256) Printf(format string, a ...interface{}) {
|
|||
|
doPrintV2(s.String(), fmt.Sprintf(format, a...))
|
|||
|
}
|
|||
|
|
|||
|
// Println print message with newline
|
|||
|
func (s *Style256) Println(a ...interface{}) {
|
|||
|
doPrintlnV2(s.String(), a)
|
|||
|
}
|
|||
|
|
|||
|
// Sprint returns rendered message
|
|||
|
func (s *Style256) Sprint(a ...interface{}) string {
|
|||
|
return RenderCode(s.Code(), a...)
|
|||
|
}
|
|||
|
|
|||
|
// Sprintf returns format and rendered message
|
|||
|
func (s *Style256) Sprintf(format string, a ...interface{}) string {
|
|||
|
return RenderString(s.Code(), fmt.Sprintf(format, a...))
|
|||
|
}
|
|||
|
|
|||
|
// Code convert to color code string
|
|||
|
func (s *Style256) Code() string {
|
|||
|
return s.String()
|
|||
|
}
|
|||
|
|
|||
|
// String convert to color code string
|
|||
|
func (s *Style256) String() string {
|
|||
|
var ss []string
|
|||
|
if s.fg[1] > 0 {
|
|||
|
ss = append(ss, fmt.Sprintf(TplFg256, s.fg[0]))
|
|||
|
}
|
|||
|
|
|||
|
if s.bg[1] > 0 {
|
|||
|
ss = append(ss, fmt.Sprintf(TplBg256, s.bg[0]))
|
|||
|
}
|
|||
|
|
|||
|
if s.opts.IsValid() {
|
|||
|
ss = append(ss, s.opts.String())
|
|||
|
}
|
|||
|
|
|||
|
return strings.Join(ss, ";")
|
|||
|
}
|