1 package text 2 3 import "strings" 4 5 // ANSICodesSupported will be true on consoles where ANSI Escape Codes/Sequences 6 // are supported. 7 var ANSICodesSupported = areANSICodesSupported() 8 9 // Escape encodes the string with the ANSI Escape Sequence. 10 // For ex.: 11 // Escape("Ghost", "") == "Ghost" 12 // Escape("Ghost", "\x1b[91m") == "\x1b[91mGhost\x1b[0m" 13 // Escape("\x1b[94mGhost\x1b[0mLady", "\x1b[91m") == "\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m" 14 // Escape("Nymeria\x1b[94mGhost\x1b[0mLady", "\x1b[91m") == "\x1b[91mNymeria\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m" 15 // Escape("Nymeria \x1b[94mGhost\x1b[0m Lady", "\x1b[91m") == "\x1b[91mNymeria \x1b[94mGhost\x1b[0m\x1b[91m Lady\x1b[0m" 16 func Escape(str string, escapeSeq string) string { 17 out := "" 18 if !strings.HasPrefix(str, EscapeStart) { 19 out += escapeSeq 20 } 21 out += strings.Replace(str, EscapeReset, EscapeReset+escapeSeq, -1) 22 if !strings.HasSuffix(out, EscapeReset) { 23 out += EscapeReset 24 } 25 if strings.Contains(out, escapeSeq+EscapeReset) { 26 out = strings.Replace(out, escapeSeq+EscapeReset, "", -1) 27 } 28 return out 29 } 30 31 // StripEscape strips all ANSI Escape Sequence from the string. 32 // For ex.: 33 // StripEscape("Ghost") == "Ghost" 34 // StripEscape("\x1b[91mGhost\x1b[0m") == "Ghost" 35 // StripEscape("\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m") == "GhostLady" 36 // StripEscape("\x1b[91mNymeria\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m") == "NymeriaGhostLady" 37 // StripEscape("\x1b[91mNymeria \x1b[94mGhost\x1b[0m\x1b[91m Lady\x1b[0m") == "Nymeria Ghost Lady" 38 func StripEscape(str string) string { 39 var out strings.Builder 40 out.Grow(RuneWidthWithoutEscSequences(str)) 41 42 isEscSeq := false 43 for _, sChr := range str { 44 if sChr == EscapeStartRune { 45 isEscSeq = true 46 } 47 if !isEscSeq { 48 out.WriteRune(sChr) 49 } 50 if isEscSeq && sChr == EscapeStopRune { 51 isEscSeq = false 52 } 53 } 54 return out.String() 55 } 56