diff --git a/src/pokesay/print.go b/src/pokesay/print.go index 9a61129..38ed9f1 100644 --- a/src/pokesay/print.go +++ b/src/pokesay/print.go @@ -195,9 +195,9 @@ func UnicodeStringLength(s string) int { for i, r := range s { if i < nRunes-1 { // detect the beginning of an ANSI escape code - // e.g. "\033[38;5;196m" + // e.g. "\x1b[38;5;196m" // ^^^ start ^ end - if s[i:i+2] == "\033[" { + if s[i:i+2] == "\x1b[" { ansiCode = true } } @@ -218,37 +218,55 @@ func UnicodeStringLength(s string) int { return totalLen } -type AnsiLineToken struct { +type ANSILineToken struct { Colour string Text string } -func TokeniseANSILine(line string) []AnsiLineToken { - tokens := make([]AnsiLineToken, 0) +func TokeniseANSIString(line string) []ANSILineToken { + tokens := make([]ANSILineToken, 0) var inAnsiCode bool - token := AnsiLineToken{} + currentColour := "" + currentText := "" + for i, r := range line { - if i < len(line)-1 { - if line[i:i+2] == "\033[" { + if r == '\x1b' { + if currentText != "" { + tokens = append(tokens, ANSILineToken{currentColour, currentText}) + currentColour = "" + currentText = "" + } + if i < len(line)-1 && line[i+1] == '[' { inAnsiCode = true + currentColour = "\x1b" } + continue } if inAnsiCode { - token.Colour += string(r) + currentColour += string(r) if r == 'm' { inAnsiCode = false } } else { - token.Text += string(r) - if i == len(line)-1 { - tokens = append(tokens, token) - } + currentText += string(r) } } + tokens = append(tokens, ANSILineToken{currentColour, currentText}) return tokens } +func ReverseANSIString(line string) string { + tokens := TokeniseANSIString(line) + reversed := "" + + for i := len(tokens) - 1; i >= 0; i-- { + reversed += tokens[i].Colour + tokens[i].Text + } + + return reversed +} + // Prints a pokemon with its name & category information. func printPokemon(args Args, index int, names []string, categoryKeys []string, GOBCowData embed.FS) { d, _ := GOBCowData.ReadFile(pokedex.EntryFpath("build/assets/cows", index)) diff --git a/test/pokesay_test.go b/test/pokesay_test.go index fa7e89c..708e96f 100644 --- a/test/pokesay_test.go +++ b/test/pokesay_test.go @@ -115,10 +115,15 @@ func TestUnicodeStringLength(test *testing.T) { Assert(expected, results, test) } -func TestTokeniseAnsiLine(test *testing.T) { +func TestTokeniseANSIString(test *testing.T) { line := "AAA  XX " - expected := []string{"", "AAA ", "", " XX ", ""} - result := pokesay.TokeniseANSILine(line) + + expected := []pokesay.ANSILineToken{ + pokesay.ANSILineToken{Colour: "", Text: "AAA "}, + pokesay.ANSILineToken{Colour: "", Text: " XX "}, + pokesay.ANSILineToken{Colour: "", Text: ""}, + } + result := pokesay.TokeniseANSIString(line) Assert(expected, result, test) } @@ -130,7 +135,7 @@ func TestFlipHorizontalLine(test *testing.T) { // The AAA should still have a purple fg // The XX should still have a red bg expected := " XX  AAA" - result := pokesay.ReverseString(line) + result := pokesay.ReverseANSIString(line) Assert(expected, result, test) }