package door import ( "bytes" "log" "strconv" "strings" ) // Profiling: // go build -gcflags=-m=2 . 2>&1 | less // What leaks to heap? // Possibly make this so it is part of an ANSI package. // DRY - Reuse. // Convert an array of int to \x1b[1;2;3m for ANSI Color // output. // https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters // https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit /* func Color(arg ...int) string { var result string = "\x1b[" for i := range arg { result += fmt.Sprintf("%d;", arg[i]) } result = result[:len(result)-1] result += "m" return result } */ func Color(arg []int) []byte { var result *bytes.Buffer = &bytes.Buffer{} result.WriteString("\x1b[") for idx, i := range arg { if idx != 0 { result.WriteString(";") } result.WriteString(strconv.Itoa(i)) } result.WriteString("m") return result.Bytes() } func ColorS(arg []int) string { var result strings.Builder result.WriteString("\x1b[") for idx, i := range arg { if idx != 0 { result.WriteString(";") } result.WriteString(strconv.Itoa(i)) } result.WriteString("m") return result.String() } // BUG(bugz) INVERSE does not work. // Would I want to do something like: // BRIGHT YELLOW or ON BLUE, and have it just change the // color or the background? Right now, I require the full // color (FG & BG). // Convert a string like "BRIGHT WHITE ON BLUE" into the expected // ANSI Color codes. You can use just the first 3 letters. // Supports BRIGHT, BOLD, BLINK and ON (to set the background color). // BLACK, RED, GREEN, BROWN / YELLOW, BLUE, MAGENTA, CYAN, WHITE // https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters // https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit func ColorText(color string) []byte { // split on spaces, uppercase, match first 3 letter var res [5]int var result []int = res[0:0] var bg bool result = append(result, 0) parts := strings.Fields(strings.ToUpper(color)) for _, part := range parts { if len(part) > 3 { part = part[:3] } switch part { case "BLA": if bg { result = append(result, 40) } else { result = append(result, 30) } case "RED": if bg { result = append(result, 41) } else { result = append(result, 31) } case "GRE": if bg { result = append(result, 42) } else { result = append(result, 32) } case "BRO", "YEL": if bg { result = append(result, 43) } else { result = append(result, 33) } case "BLU": if bg { result = append(result, 44) } else { result = append(result, 34) } case "MAG": if bg { result = append(result, 45) } else { result = append(result, 35) } case "CYA": if bg { result = append(result, 46) } else { result = append(result, 36) } case "WHI": if bg { result = append(result, 47) } else { result = append(result, 37) } case "BOL", "BRI": result = append(result, 1) case "ON": bg = true case "BLI": result = append(result, 5) // Invert is't well supported in terminals // case "INV": // result = append(result, 7) default: log.Panicf("ColorText Unknown: [%s] in %s\n", part, color) } } return Color(result) } func ColorTextS(color string) string { // split on spaces, uppercase, match first 3 letter var res [5]int var result []int = res[0:0] var bg bool result = append(result, 0) parts := strings.Fields(strings.ToUpper(color)) for _, part := range parts { if len(part) > 3 { part = part[:3] } switch part { case "BLA": if bg { result = append(result, 40) } else { result = append(result, 30) } case "RED": if bg { result = append(result, 41) } else { result = append(result, 31) } case "GRE": if bg { result = append(result, 42) } else { result = append(result, 32) } case "BRO", "YEL": if bg { result = append(result, 43) } else { result = append(result, 33) } case "BLU": if bg { result = append(result, 44) } else { result = append(result, 34) } case "MAG": if bg { result = append(result, 45) } else { result = append(result, 35) } case "CYA": if bg { result = append(result, 46) } else { result = append(result, 36) } case "WHI": if bg { result = append(result, 47) } else { result = append(result, 37) } case "BOL", "BRI": result = append(result, 1) case "ON": bg = true case "BLI": result = append(result, 5) // Invert is't well supported in terminals // case "INV": // result = append(result, 7) default: log.Panicf("ColorText Unknown: [%s] in %s\n", part, color) } } return ColorS(result) }