From 59f75021fec5f0c5dbb250ae18fd82b356f52834 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Sat, 5 Nov 2022 11:52:56 -0700 Subject: [PATCH 01/29] adding start of style_parser_test --- style_parser_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 style_parser_test.go diff --git a/style_parser_test.go b/style_parser_test.go new file mode 100644 index 0000000..21587b2 --- /dev/null +++ b/style_parser_test.go @@ -0,0 +1,16 @@ +package termui + +import ( + "testing" +) + +func TestParseStyles(t *testing.T) { + cells := ParseStyles("test [blue](fg:blue)", NewStyle(ColorWhite)) + if cells[0].Style.Fg != 7 { + t.Fatal("normal text fg is wrong") + } + if cells[5].Style.Fg != 4 { + t.Fatal("blue text fg is wrong") + } + +} From a5730c90679af10c5f42e6d5a35defd8f3947166 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Sat, 5 Nov 2022 11:56:04 -0700 Subject: [PATCH 02/29] adding failing test for [text] and no color info after --- style_parser_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/style_parser_test.go b/style_parser_test.go index 21587b2..d3e7ff6 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -13,4 +13,8 @@ func TestParseStyles(t *testing.T) { t.Fatal("blue text fg is wrong") } + cells = ParseStyles("[hi]", NewStyle(ColorWhite)) + if len(cells) != 4 { + t.Fatal("missing closing ]") + } } From f047fb3200034fc8b4c47b7425d3bf90e5e19152 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 02:43:40 -0800 Subject: [PATCH 03/29] good failing tests showing the problem --- style_parser_test.go | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/style_parser_test.go b/style_parser_test.go index d3e7ff6..7a0d625 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,20 +1,41 @@ package termui import ( + "strings" "testing" ) func TestParseStyles(t *testing.T) { cells := ParseStyles("test [blue](fg:blue)", NewStyle(ColorWhite)) - if cells[0].Style.Fg != 7 { - t.Fatal("normal text fg is wrong") - } - if cells[5].Style.Fg != 4 { - t.Fatal("blue text fg is wrong") + text := textFromCells(cells) + if text != "test blue" { + t.Fatal("wrong text", text) } - cells = ParseStyles("[hi]", NewStyle(ColorWhite)) - if len(cells) != 4 { - t.Fatal("missing closing ]") + cells = ParseStyles("[blue](fg:blue) [1] ", NewStyle(ColorWhite)) + text = textFromCells(cells) + if text != "blue [1] hello" { + t.Fatal("wrong text", text) } + + cells = ParseStyles("[0]", NewStyle(ColorWhite)) + text = textFromCells(cells) + if text != "[0]" { + t.Fatal("wrong text", text) + } + + cells = ParseStyles("[", NewStyle(ColorWhite)) + text = textFromCells(cells) + if text != "[" { + t.Fatal("wrong text", text) + } + +} + +func textFromCells(cells []Cell) string { + buff := []string{} + for _, cell := range cells { + buff = append(buff, string(cell.Rune)) + } + return strings.Join(buff, "") } From 2bd947efbba2da0d281fb9be393b5fb579a7b5bb Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 02:44:37 -0800 Subject: [PATCH 04/29] fixing one test with wrong logic --- style_parser_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/style_parser_test.go b/style_parser_test.go index 7a0d625..7d7a808 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -12,9 +12,9 @@ func TestParseStyles(t *testing.T) { t.Fatal("wrong text", text) } - cells = ParseStyles("[blue](fg:blue) [1] ", NewStyle(ColorWhite)) + cells = ParseStyles("[blue](fg:blue) [1]", NewStyle(ColorWhite)) text = textFromCells(cells) - if text != "blue [1] hello" { + if text != "blue [1]" { t.Fatal("wrong text", text) } From 94288e85a1c0c63acd52ac0017df6aa2fd828499 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 03:00:20 -0800 Subject: [PATCH 05/29] test to make sure current logic stays working --- style_parser_test.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/style_parser_test.go b/style_parser_test.go index 7d7a808..9f0ec4b 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -6,7 +6,33 @@ import ( ) func TestParseStyles(t *testing.T) { - cells := ParseStyles("test [blue](fg:blue)", NewStyle(ColorWhite)) + cells := ParseStyles("test [blue](fg:blue,bg:white,mod:bold)", NewStyle(ColorWhite)) + if len(cells) != 9 { + t.Fatal("wrong length", len(cells)) + } + for i := 0; i < 5; i++ { + if cells[i].Style.Fg != ColorWhite { + t.Fatal("wrong fg color", cells[i]) + } + if cells[i].Style.Bg != ColorClear { + t.Fatal("wrong bg color", cells[i]) + } + if cells[i].Style.Modifier != ModifierClear { + t.Fatal("wrong mod", cells[i]) + } + } + for i := 5; i < len(cells); i++ { + if cells[i].Style.Fg != ColorBlue { + t.Fatal("wrong fg color", cells[i]) + } + if cells[i].Style.Bg != ColorWhite { + t.Fatal("wrong bg color", cells[i]) + } + if cells[i].Style.Modifier != ModifierBold { + t.Fatal("wrong mod", cells[i]) + } + } + text := textFromCells(cells) if text != "test blue" { t.Fatal("wrong text", text) From c4fdef993a55eaf1651ff8608cf61d13894a2c0d Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 03:46:07 -0800 Subject: [PATCH 06/29] very broken but just starting logic for new ParseStyles func --- style_parser.go | 19 +++++++++++++++++++ style_parser_test.go | 9 +++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/style_parser.go b/style_parser.go index ce537da..8f77efd 100644 --- a/style_parser.go +++ b/style_parser.go @@ -70,11 +70,30 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } +func processToken(token string) { +} + // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. // Uses defaultStyle for any text without an embedded style. // Syntax is of the form [text](fg:,mod:,bg:). // Ordering does not matter. All fields are optional. func ParseStyles(s string, defaultStyle Style) []Cell { + //test [blue](fg:blue,bg:white,mod:bold) + cells := []Cell{} + + tokens := strings.Split(s, "](") + if len(tokens) == 1 { + // easy case, not styled string + return cells + } + for i := len(tokens) - 1; i > 0; i-- { + processToken(tokens[i]) + } + + return cells +} + +func ParseStyles2(s string, defaultStyle Style) []Cell { cells := []Cell{} runes := []rune(s) state := parserStateDefault diff --git a/style_parser_test.go b/style_parser_test.go index 9f0ec4b..0c8b5b2 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -6,8 +6,9 @@ import ( ) func TestParseStyles(t *testing.T) { - cells := ParseStyles("test [blue](fg:blue,bg:white,mod:bold)", NewStyle(ColorWhite)) - if len(cells) != 9 { + cells := ParseStyles("test nothing", NewStyle(ColorWhite)) + cells = ParseStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)", NewStyle(ColorWhite)) + if len(cells) != 17 { t.Fatal("wrong length", len(cells)) } for i := 0; i < 5; i++ { @@ -21,7 +22,7 @@ func TestParseStyles(t *testing.T) { t.Fatal("wrong mod", cells[i]) } } - for i := 5; i < len(cells); i++ { + for i := 5; i < 9; i++ { if cells[i].Style.Fg != ColorBlue { t.Fatal("wrong fg color", cells[i]) } @@ -34,7 +35,7 @@ func TestParseStyles(t *testing.T) { } text := textFromCells(cells) - if text != "test blue" { + if text != "test blue and red" { t.Fatal("wrong text", text) } From 99a9b416b7d0ba0f549b6cf2ea3b792d91ab579f Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 03:55:40 -0800 Subject: [PATCH 07/29] returning a styleString --- style_parser.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/style_parser.go b/style_parser.go index 8f77efd..5eb33a7 100644 --- a/style_parser.go +++ b/style_parser.go @@ -70,7 +70,13 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } -func processToken(token string) { +func processToken(token string) string { + index := strings.Index(token, ")") + if index == -1 { + return "" + } + styleString := token[0:index] + return styleString } // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. @@ -86,8 +92,10 @@ func ParseStyles(s string, defaultStyle Style) []Cell { // easy case, not styled string return cells } - for i := len(tokens) - 1; i > 0; i-- { - processToken(tokens[i]) + + styleString := "" + for i := len(tokens) - 1; i >= 0; i-- { + styleString = processToken(tokens[i]) } return cells From 4d1aaf17a715f8c1f4e115b428339356dde43c3d Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 04:21:40 -0800 Subject: [PATCH 08/29] adding new test for PrepareStyles --- style_parser.go | 31 +++++++++++++++++++++++++------ style_parser_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/style_parser.go b/style_parser.go index 5eb33a7..2004b84 100644 --- a/style_parser.go +++ b/style_parser.go @@ -5,6 +5,7 @@ package termui import ( + "fmt" "strings" ) @@ -25,6 +26,11 @@ const ( type parserState uint +type PreparedStyle struct { + Text string + Style string +} + const ( parserStateDefault parserState = iota parserStateStyleItems @@ -70,13 +76,20 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } -func processToken(token string) string { +func processToken(token, previous string) (string, string) { + fmt.Println("1", token) index := strings.Index(token, ")") if index == -1 { - return "" + return "", "" } styleString := token[0:index] - return styleString + restOfString := token[index:] + return styleString, restOfString +} + +func PrepareStyles(s string) []PreparedStyle { + items := []PreparedStyle{} + return items } // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. @@ -93,11 +106,17 @@ func ParseStyles(s string, defaultStyle Style) []Cell { return cells } - styleString := "" - for i := len(tokens) - 1; i >= 0; i-- { - styleString = processToken(tokens[i]) + styleString, rest := processToken(tokens[len(tokens)-1], "") + fmt.Println("2", styleString, rest) + for i := len(tokens) - 2; i >= 0; i-- { + styleString, rest = processToken(tokens[i], styleString) + fmt.Println("3", styleString, rest) } + //1 fg:red) + //1 fg:blue,bg:white,mod:bold) and [red + //1 test [blue + return cells } diff --git a/style_parser_test.go b/style_parser_test.go index 0c8b5b2..c89eaf4 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -5,6 +5,37 @@ import ( "testing" ) +func TestPrepareStyles(t *testing.T) { + items := PrepareStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)") + if len(items) != 4 { + t.Fatal("wrong length", len(items)) + } + if items[0].Text != "test " { + t.Fatal("wrong text", items[0].Text) + } + if items[0].Style != "" { + t.Fatal("wrong text", items[0].Style) + } + if items[1].Text != "blue" { + t.Fatal("wrong text", items[1].Text) + } + if items[1].Style != "fg:blue,bg:white,mod:bold" { + t.Fatal("wrong text", items[1].Style) + } + if items[2].Text != " and " { + t.Fatal("wrong text", items[2].Text) + } + if items[2].Style != "" { + t.Fatal("wrong text", items[2].Style) + } + if items[3].Text != "red" { + t.Fatal("wrong text", items[3].Text) + } + if items[3].Style != "fg:red" { + t.Fatal("wrong text", items[3].Style) + } +} + func TestParseStyles(t *testing.T) { cells := ParseStyles("test nothing", NewStyle(ColorWhite)) cells = ParseStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)", NewStyle(ColorWhite)) From 70b8f7489a0da34cc625e9af848a8e052ddec33e Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 04:24:12 -0800 Subject: [PATCH 09/29] testing easy case of no style --- style_parser.go | 6 ++++++ style_parser_test.go | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/style_parser.go b/style_parser.go index 2004b84..8cc26b8 100644 --- a/style_parser.go +++ b/style_parser.go @@ -89,6 +89,12 @@ func processToken(token, previous string) (string, string) { func PrepareStyles(s string) []PreparedStyle { items := []PreparedStyle{} + tokens := strings.Split(s, "](") + if len(tokens) == 1 { + // easy case, not styled string + ps := PreparedStyle{s, ""} + return []PreparedStyle{ps} + } return items } diff --git a/style_parser_test.go b/style_parser_test.go index c89eaf4..c71e473 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -6,7 +6,11 @@ import ( ) func TestPrepareStyles(t *testing.T) { - items := PrepareStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)") + items := PrepareStyles("test no style") + if len(items) != 1 { + t.Fatal("wrong length", len(items)) + } + items = PrepareStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)") if len(items) != 4 { t.Fatal("wrong length", len(items)) } From 90c992f2e60f6eb1752d363def0d35fdf4544b47 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 08:26:51 -0800 Subject: [PATCH 10/29] progress with parsing --- style_parser.go | 40 ++++++++++++++++++++++++++++++++++++++++ style_parser_test.go | 14 ++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/style_parser.go b/style_parser.go index 8cc26b8..1f18712 100644 --- a/style_parser.go +++ b/style_parser.go @@ -87,6 +87,44 @@ func processToken(token, previous string) (string, string) { return styleString, restOfString } +func lookLeftForBracket(s string) (string, string) { + index := strings.LastIndex(s, "[") + return s[0:index], s[index+1:] +} + +func lookRightForEndStyle(s string) (string, string) { + index := strings.Index(s, ")") + return s[0:index], s[index+1:] +} + +func BreakByStyles(s string) []string { + // "test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)" + tokens := strings.Split(s, "](") + if len(tokens) == 1 { + return tokens + } + + styleString := "" + remainder := tokens[0] + i := 1 + for { + prefix, item := lookLeftForBracket(remainder) + styleString, remainder = lookRightForEndStyle(tokens[i]) + i++ + fmt.Println(i, prefix) + fmt.Println(i, item) + fmt.Println(i, styleString) + fmt.Println(i, remainder) + if !strings.Contains(remainder, "[") { + break + } + } + + buffer := []string{} + + return buffer +} + func PrepareStyles(s string) []PreparedStyle { items := []PreparedStyle{} tokens := strings.Split(s, "](") @@ -95,6 +133,8 @@ func PrepareStyles(s string) []PreparedStyle { ps := PreparedStyle{s, ""} return []PreparedStyle{ps} } + + fmt.Println(strings.Join(tokens, "|")) return items } diff --git a/style_parser_test.go b/style_parser_test.go index c71e473..a47080e 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,16 +1,25 @@ package termui import ( - "strings" "testing" ) +func TestBreakByStyles(t *testing.T) { + items := BreakByStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red) and maybe even [foo](more)!") + //test [blue|fg:blue,bg:white,mod:bold) and [red|fg:red) + //test|blue|fg:blue,bg:white,mod:bold| and |red|fg:red + if len(items) != 6 { + t.Fatal("wrong length", len(items)) + } +} + func TestPrepareStyles(t *testing.T) { items := PrepareStyles("test no style") if len(items) != 1 { t.Fatal("wrong length", len(items)) } items = PrepareStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)") + //test [blue|fg:blue,bg:white,mod:bold) and [red|fg:red) if len(items) != 4 { t.Fatal("wrong length", len(items)) } @@ -40,6 +49,7 @@ func TestPrepareStyles(t *testing.T) { } } +/* func TestParseStyles(t *testing.T) { cells := ParseStyles("test nothing", NewStyle(ColorWhite)) cells = ParseStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)", NewStyle(ColorWhite)) @@ -100,4 +110,4 @@ func textFromCells(cells []Cell) string { buff = append(buff, string(cell.Rune)) } return strings.Join(buff, "") -} +}*/ From 22d00586dbfe72c221f3ed1456839d95c147abf4 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 08:54:53 -0800 Subject: [PATCH 11/29] getting ready to link up styles --- style_parser.go | 65 ++++++++++++++++++++------------------------ style_parser_test.go | 50 ++++++---------------------------- 2 files changed, 38 insertions(+), 77 deletions(-) diff --git a/style_parser.go b/style_parser.go index 1f18712..9cc65fa 100644 --- a/style_parser.go +++ b/style_parser.go @@ -26,11 +26,6 @@ const ( type parserState uint -type PreparedStyle struct { - Text string - Style string -} - const ( parserStateDefault parserState = iota parserStateStyleItems @@ -98,12 +93,12 @@ func lookRightForEndStyle(s string) (string, string) { } func BreakByStyles(s string) []string { - // "test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)" tokens := strings.Split(s, "](") if len(tokens) == 1 { return tokens } + buff := []string{} styleString := "" remainder := tokens[0] i := 1 @@ -111,31 +106,30 @@ func BreakByStyles(s string) []string { prefix, item := lookLeftForBracket(remainder) styleString, remainder = lookRightForEndStyle(tokens[i]) i++ - fmt.Println(i, prefix) - fmt.Println(i, item) - fmt.Println(i, styleString) - fmt.Println(i, remainder) + buff = append(buff, prefix) + buff = append(buff, item) + buff = append(buff, styleString) if !strings.Contains(remainder, "[") { + buff = append(buff, remainder) break } } - buffer := []string{} - - return buffer + return buff } -func PrepareStyles(s string) []PreparedStyle { - items := []PreparedStyle{} - tokens := strings.Split(s, "](") - if len(tokens) == 1 { - // easy case, not styled string - ps := PreparedStyle{s, ""} - return []PreparedStyle{ps} +func containsColorOrMod(s string) bool { + if strings.Contains(s, "fg:") { + return true + } + if strings.Contains(s, "bg:") { + return true + } + if strings.Contains(s, "mod:") { + return true } - fmt.Println(strings.Join(tokens, "|")) - return items + return false } // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. @@ -143,26 +137,27 @@ func PrepareStyles(s string) []PreparedStyle { // Syntax is of the form [text](fg:,mod:,bg:). // Ordering does not matter. All fields are optional. func ParseStyles(s string, defaultStyle Style) []Cell { - //test [blue](fg:blue,bg:white,mod:bold) cells := []Cell{} - tokens := strings.Split(s, "](") - if len(tokens) == 1 { - // easy case, not styled string + fmt.Println("11") + items := BreakByStyles(s) + fmt.Println("11", len(items)) + if len(items) == 1 { + runes := []rune(s) + for _, _rune := range runes { + cells = append(cells, Cell{_rune, defaultStyle}) + } return cells } - styleString, rest := processToken(tokens[len(tokens)-1], "") - fmt.Println("2", styleString, rest) - for i := len(tokens) - 2; i >= 0; i-- { - styleString, rest = processToken(tokens[i], styleString) - fmt.Println("3", styleString, rest) + //test blue fg:blue,bg:white,mod:bold and red fg:red and maybe even foo bg:red ! + for i := len(items) - 1; i > -1; i-- { + if containsColorOrMod(items[i]) { + } else { + fmt.Println(items[i]) + } } - //1 fg:red) - //1 fg:blue,bg:white,mod:bold) and [red - //1 test [blue - return cells } diff --git a/style_parser_test.go b/style_parser_test.go index a47080e..8618d78 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,55 +1,21 @@ package termui import ( + "strings" "testing" ) func TestBreakByStyles(t *testing.T) { - items := BreakByStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red) and maybe even [foo](more)!") - //test [blue|fg:blue,bg:white,mod:bold) and [red|fg:red) - //test|blue|fg:blue,bg:white,mod:bold| and |red|fg:red - if len(items) != 6 { + items := BreakByStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + if len(items) != 10 { t.Fatal("wrong length", len(items)) } + text := strings.Join(items, " ") + if text != "test blue fg:blue,bg:white,mod:bold and red fg:red and maybe even foo bg:red !" { + t.Fatal("wrong text", text) + } } -func TestPrepareStyles(t *testing.T) { - items := PrepareStyles("test no style") - if len(items) != 1 { - t.Fatal("wrong length", len(items)) - } - items = PrepareStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)") - //test [blue|fg:blue,bg:white,mod:bold) and [red|fg:red) - if len(items) != 4 { - t.Fatal("wrong length", len(items)) - } - if items[0].Text != "test " { - t.Fatal("wrong text", items[0].Text) - } - if items[0].Style != "" { - t.Fatal("wrong text", items[0].Style) - } - if items[1].Text != "blue" { - t.Fatal("wrong text", items[1].Text) - } - if items[1].Style != "fg:blue,bg:white,mod:bold" { - t.Fatal("wrong text", items[1].Style) - } - if items[2].Text != " and " { - t.Fatal("wrong text", items[2].Text) - } - if items[2].Style != "" { - t.Fatal("wrong text", items[2].Style) - } - if items[3].Text != "red" { - t.Fatal("wrong text", items[3].Text) - } - if items[3].Style != "fg:red" { - t.Fatal("wrong text", items[3].Style) - } -} - -/* func TestParseStyles(t *testing.T) { cells := ParseStyles("test nothing", NewStyle(ColorWhite)) cells = ParseStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)", NewStyle(ColorWhite)) @@ -110,4 +76,4 @@ func textFromCells(cells []Cell) string { buff = append(buff, string(cell.Rune)) } return strings.Join(buff, "") -}*/ +} From c77684f4348c1b6692b91b0c2178fa9ff786d2f7 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 11:25:41 -0800 Subject: [PATCH 12/29] progress with style --- style_parser.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/style_parser.go b/style_parser.go index 9cc65fa..9af7210 100644 --- a/style_parser.go +++ b/style_parser.go @@ -151,10 +151,13 @@ func ParseStyles(s string, defaultStyle Style) []Cell { } //test blue fg:blue,bg:white,mod:bold and red fg:red and maybe even foo bg:red ! + style := defaultStyle for i := len(items) - 1; i > -1; i-- { if containsColorOrMod(items[i]) { + style = readStyle([]rune(items[i]), defaultStyle) } else { - fmt.Println(items[i]) + cells = append(cells, RunesToStyledCells([]rune(items[i]), style)...) + style = defaultStyle } } From eaf7f8d6e68cfc019a42d90f91370a3c4db16d82 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 11:30:57 -0800 Subject: [PATCH 13/29] clean up and better order --- style_parser.go | 20 ++++---------------- style_parser_test.go | 4 ++++ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/style_parser.go b/style_parser.go index 9af7210..718c0bc 100644 --- a/style_parser.go +++ b/style_parser.go @@ -5,7 +5,6 @@ package termui import ( - "fmt" "strings" ) @@ -71,17 +70,6 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } -func processToken(token, previous string) (string, string) { - fmt.Println("1", token) - index := strings.Index(token, ")") - if index == -1 { - return "", "" - } - styleString := token[0:index] - restOfString := token[index:] - return styleString, restOfString -} - func lookLeftForBracket(s string) (string, string) { index := strings.LastIndex(s, "[") return s[0:index], s[index+1:] @@ -113,6 +101,9 @@ func BreakByStyles(s string) []string { buff = append(buff, remainder) break } + if i > len(tokens)-1 { + break + } } return buff @@ -139,9 +130,7 @@ func containsColorOrMod(s string) bool { func ParseStyles(s string, defaultStyle Style) []Cell { cells := []Cell{} - fmt.Println("11") items := BreakByStyles(s) - fmt.Println("11", len(items)) if len(items) == 1 { runes := []rune(s) for _, _rune := range runes { @@ -150,13 +139,12 @@ func ParseStyles(s string, defaultStyle Style) []Cell { return cells } - //test blue fg:blue,bg:white,mod:bold and red fg:red and maybe even foo bg:red ! style := defaultStyle for i := len(items) - 1; i > -1; i-- { if containsColorOrMod(items[i]) { style = readStyle([]rune(items[i]), defaultStyle) } else { - cells = append(cells, RunesToStyledCells([]rune(items[i]), style)...) + cells = append(RunesToStyledCells([]rune(items[i]), style), cells...) style = defaultStyle } } diff --git a/style_parser_test.go b/style_parser_test.go index 8618d78..9d9893a 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,6 +1,7 @@ package termui import ( + "fmt" "strings" "testing" ) @@ -19,6 +20,9 @@ func TestBreakByStyles(t *testing.T) { func TestParseStyles(t *testing.T) { cells := ParseStyles("test nothing", NewStyle(ColorWhite)) cells = ParseStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)", NewStyle(ColorWhite)) + fmt.Println(cells) + text2 := textFromCells(cells) + fmt.Println(text2) if len(cells) != 17 { t.Fatal("wrong length", len(cells)) } From f893b6f7faa0e48f9b452d0a1973f07662a5dcbb Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Mon, 7 Nov 2022 11:34:45 -0800 Subject: [PATCH 14/29] more cleanup of printing --- style_parser_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/style_parser_test.go b/style_parser_test.go index 9d9893a..8618d78 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,7 +1,6 @@ package termui import ( - "fmt" "strings" "testing" ) @@ -20,9 +19,6 @@ func TestBreakByStyles(t *testing.T) { func TestParseStyles(t *testing.T) { cells := ParseStyles("test nothing", NewStyle(ColorWhite)) cells = ParseStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red)", NewStyle(ColorWhite)) - fmt.Println(cells) - text2 := textFromCells(cells) - fmt.Println(text2) if len(cells) != 17 { t.Fatal("wrong length", len(cells)) } From 3be455ecc53b2de8d6f0a2990e9cf1290669c5e5 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 06:09:14 -0800 Subject: [PATCH 15/29] broken but good new direction --- style_parser.go | 58 +++++++++++++++++++++++++++----------------- style_parser_test.go | 17 +++++++++++-- 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/style_parser.go b/style_parser.go index 718c0bc..fcab742 100644 --- a/style_parser.go +++ b/style_parser.go @@ -5,6 +5,7 @@ package termui import ( + "fmt" "strings" ) @@ -70,42 +71,55 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } -func lookLeftForBracket(s string) (string, string) { - index := strings.LastIndex(s, "[") - return s[0:index], s[index+1:] +func lookLeftForBracket(s string) int { + return strings.LastIndex(s, "[") } -func lookRightForEndStyle(s string) (string, string) { - index := strings.Index(s, ")") - return s[0:index], s[index+1:] +func lookRightForEndStyle(s string) int { + return strings.Index(s, ")") } func BreakByStyles(s string) []string { + fmt.Println(s) tokens := strings.Split(s, "](") if len(tokens) == 1 { return tokens } buff := []string{} - styleString := "" - remainder := tokens[0] - i := 1 - for { - prefix, item := lookLeftForBracket(remainder) - styleString, remainder = lookRightForEndStyle(tokens[i]) - i++ - buff = append(buff, prefix) - buff = append(buff, item) - buff = append(buff, styleString) - if !strings.Contains(remainder, "[") { - buff = append(buff, remainder) - break - } - if i > len(tokens)-1 { - break + + // test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)! + for i, token := range tokens { + if i%2 == 0 { + index := lookLeftForBracket(token) + fmt.Println(i, "even", len(token), index) + } else { + index := lookRightForEndStyle(token) + fmt.Println(i, "odd", len(token), index) } + buff = append(buff, token) } + /* + styleString := "" + remainder := tokens[0] + i := 1 + for { + prefix, item := lookLeftForBracket(remainder) + styleString, remainder = lookRightForEndStyle(tokens[i]) + i++ + buff = append(buff, prefix) + buff = append(buff, item) + buff = append(buff, styleString) + if !strings.Contains(remainder, "*") { + buff = append(buff, remainder) + break + } + if i > len(tokens)-1 { + break + } + }*/ + return buff } diff --git a/style_parser_test.go b/style_parser_test.go index 8618d78..9be4b5e 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,12 +1,18 @@ package termui import ( + "fmt" "strings" "testing" ) -func TestBreakByStyles(t *testing.T) { - items := BreakByStyles("test [blue](fg:blue,bg:white,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") +func TestBreakByStylesComplex(t *testing.T) { + items := BreakByStyles("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + // "test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!" + // 01234567890123456789012345678 + // 0- 4 normal + // 5-28 style + // 29- if len(items) != 10 { t.Fatal("wrong length", len(items)) } @@ -15,6 +21,13 @@ func TestBreakByStyles(t *testing.T) { t.Fatal("wrong text", text) } } +func TestBreakByStylesSimpler(t *testing.T) { + items := BreakByStyles("[blue](fg:blue) [1]") + // [blue](fg:blue) [1] + // 012345678901234 + // 0-14, rest + fmt.Println(items, len(items)) +} func TestParseStyles(t *testing.T) { cells := ParseStyles("test nothing", NewStyle(ColorWhite)) From 4901307000ae49f13160570208487a79f89c3831 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 06:19:35 -0800 Subject: [PATCH 16/29] StyleStringPosition struct helping --- style_parser.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/style_parser.go b/style_parser.go index fcab742..eba0fa3 100644 --- a/style_parser.go +++ b/style_parser.go @@ -79,6 +79,12 @@ func lookRightForEndStyle(s string) int { return strings.Index(s, ")") } +type StyleStringPosition struct { + Start int + End int + IsStyle bool +} + func BreakByStyles(s string) []string { fmt.Println(s) tokens := strings.Split(s, "](") @@ -86,19 +92,31 @@ func BreakByStyles(s string) []string { return tokens } + ssps := []StyleStringPosition{} buff := []string{} // test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)! + offset := 0 for i, token := range tokens { if i%2 == 0 { index := lookLeftForBracket(token) + ssp := StyleStringPosition{offset, offset + index, false} + ssps = append(ssps, ssp) + ssp = StyleStringPosition{offset + index, offset + len(token), true} + ssps = append(ssps, ssp) fmt.Println(i, "even", len(token), index) } else { index := lookRightForEndStyle(token) + ssp := StyleStringPosition{offset, offset + index, true} + ssps = append(ssps, ssp) + ssp = StyleStringPosition{offset + index, offset + len(token), false} + ssps = append(ssps, ssp) fmt.Println(i, "odd", len(token), index) } + offset += len(token) + 2 buff = append(buff, token) } + fmt.Println(ssps) /* styleString := "" From 2c85cd905f7ca5b3b643cd8e18d4099f84883bd4 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 08:22:41 -0800 Subject: [PATCH 17/29] better logic than split --- style_parser.go | 141 ++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 71 deletions(-) diff --git a/style_parser.go b/style_parser.go index eba0fa3..247b8d6 100644 --- a/style_parser.go +++ b/style_parser.go @@ -87,74 +87,72 @@ type StyleStringPosition struct { func BreakByStyles(s string) []string { fmt.Println(s) - tokens := strings.Split(s, "](") - if len(tokens) == 1 { - return tokens + index := strings.Index(s, "](") + if index == -1 { + return []string{s} } - ssps := []StyleStringPosition{} buff := []string{} - // test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)! - offset := 0 - for i, token := range tokens { - if i%2 == 0 { - index := lookLeftForBracket(token) - ssp := StyleStringPosition{offset, offset + index, false} - ssps = append(ssps, ssp) - ssp = StyleStringPosition{offset + index, offset + len(token), true} - ssps = append(ssps, ssp) - fmt.Println(i, "even", len(token), index) - } else { - index := lookRightForEndStyle(token) - ssp := StyleStringPosition{offset, offset + index, true} - ssps = append(ssps, ssp) - ssp = StyleStringPosition{offset + index, offset + len(token), false} - ssps = append(ssps, ssp) - fmt.Println(i, "odd", len(token), index) + toProcess := s + for { + fmt.Println(index) + toProcess = toProcess[index+1:] + fmt.Println(toProcess) + index = strings.Index(toProcess, "](") + if index == -1 { + break } - offset += len(token) + 2 - buff = append(buff, token) } - fmt.Println(ssps) + + // test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)! /* - styleString := "" - remainder := tokens[0] - i := 1 - for { - prefix, item := lookLeftForBracket(remainder) - styleString, remainder = lookRightForEndStyle(tokens[i]) - i++ - buff = append(buff, prefix) - buff = append(buff, item) - buff = append(buff, styleString) - if !strings.Contains(remainder, "*") { - buff = append(buff, remainder) - break + offset := 0 + for i, token := range tokens { + if i%2 == 0 { + index := lookLeftForBracket(token) + ssp := StyleStringPosition{offset, offset + index, false} + ssps = append(ssps, ssp) + ssp = StyleStringPosition{offset + index, offset + len(token), true} + ssps = append(ssps, ssp) + fmt.Println(i, "even", len(token), index) + } else { + index := lookRightForEndStyle(token) + ssp := StyleStringPosition{offset, offset + index, true} + ssps = append(ssps, ssp) + ssp = StyleStringPosition{offset + index, offset + len(token), false} + ssps = append(ssps, ssp) + fmt.Println(i, "odd", len(token), index) } - if i > len(tokens)-1 { - break - } - }*/ + offset += len(token) + 2 + buff = append(buff, token) + } + fmt.Println(ssps) + + + styleString := "" + remainder := tokens[0] + i := 1 + for { + prefix, item := lookLeftForBracket(remainder) + styleString, remainder = lookRightForEndStyle(tokens[i]) + i++ + buff = append(buff, prefix) + buff = append(buff, item) + buff = append(buff, styleString) + if !strings.Contains(remainder, "*") { + buff = append(buff, remainder) + break + } + if i > len(tokens)-1 { + break + } + }*/ return buff } -func containsColorOrMod(s string) bool { - if strings.Contains(s, "fg:") { - return true - } - if strings.Contains(s, "bg:") { - return true - } - if strings.Contains(s, "mod:") { - return true - } - - return false -} - // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. // Uses defaultStyle for any text without an embedded style. // Syntax is of the form [text](fg:,mod:,bg:). @@ -162,25 +160,26 @@ func containsColorOrMod(s string) bool { func ParseStyles(s string, defaultStyle Style) []Cell { cells := []Cell{} - items := BreakByStyles(s) - if len(items) == 1 { - runes := []rune(s) - for _, _rune := range runes { - cells = append(cells, Cell{_rune, defaultStyle}) + /* + items := BreakByStyles(s) + if len(items) == 1 { + runes := []rune(s) + for _, _rune := range runes { + cells = append(cells, Cell{_rune, defaultStyle}) + } + return cells } - return cells - } - style := defaultStyle - for i := len(items) - 1; i > -1; i-- { - if containsColorOrMod(items[i]) { - style = readStyle([]rune(items[i]), defaultStyle) - } else { - cells = append(RunesToStyledCells([]rune(items[i]), style), cells...) - style = defaultStyle + style := defaultStyle + for i := len(items) - 1; i > -1; i-- { + if containsColorOrMod(items[i]) { + style = readStyle([]rune(items[i]), defaultStyle) + } else { + cells = append(RunesToStyledCells([]rune(items[i]), style), cells...) + style = defaultStyle + } } - } - + */ return cells } From 291e9577ef97e78871ad4d3337eab6774971db2a Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 08:59:48 -0800 Subject: [PATCH 18/29] moving to new FindStylePositions as first call --- style_parser.go | 15 +++++++++++---- style_parser_test.go | 12 +++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/style_parser.go b/style_parser.go index 247b8d6..39fd81e 100644 --- a/style_parser.go +++ b/style_parser.go @@ -86,25 +86,32 @@ type StyleStringPosition struct { } func BreakByStyles(s string) []string { + return []string{} +} + +func FindStylePositions(s string) []int { fmt.Println(s) index := strings.Index(s, "](") if index == -1 { - return []string{s} + return []int{} } - buff := []string{} + buff := []int{} toProcess := s + offset := 0 for { - fmt.Println(index) + buff = append(buff, index+offset) toProcess = toProcess[index+1:] - fmt.Println(toProcess) + offset += index + 1 index = strings.Index(toProcess, "](") if index == -1 { break } } + return buff + // test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)! /* diff --git a/style_parser_test.go b/style_parser_test.go index 9be4b5e..94e5134 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -6,13 +6,15 @@ import ( "testing" ) +func TestFindStylePositions(t *testing.T) { + items := FindStylePositions("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + if len(items) != 3 { + t.Fatal("wrong length", len(items)) + } +} + func TestBreakByStylesComplex(t *testing.T) { items := BreakByStyles("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") - // "test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!" - // 01234567890123456789012345678 - // 0- 4 normal - // 5-28 style - // 29- if len(items) != 10 { t.Fatal("wrong length", len(items)) } From f9eac67f008f5746535039f1f1707f2c52b85b4d Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 09:04:17 -0800 Subject: [PATCH 19/29] index checks for test --- style_parser_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/style_parser_test.go b/style_parser_test.go index 94e5134..d3088d2 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -11,6 +11,15 @@ func TestFindStylePositions(t *testing.T) { if len(items) != 3 { t.Fatal("wrong length", len(items)) } + if items[0] != 10 { + t.Fatal("wrong index", items[0]) + } + if items[1] != 38 { + t.Fatal("wrong index", items[1]) + } + if items[2] != 67 { + t.Fatal("wrong index", items[2]) + } } func TestBreakByStylesComplex(t *testing.T) { From ea81b84555700847898a4c549e2fbfa0b84af6c3 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 09:11:41 -0800 Subject: [PATCH 20/29] clean up and new broken test but with good indexes to hit --- style_parser.go | 12 ++++++------ style_parser_test.go | 25 +++++++++++-------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/style_parser.go b/style_parser.go index 39fd81e..2854c00 100644 --- a/style_parser.go +++ b/style_parser.go @@ -79,14 +79,14 @@ func lookRightForEndStyle(s string) int { return strings.Index(s, ")") } -type StyleStringPosition struct { - Start int - End int - IsStyle bool +type StyleBlock struct { + Start int + End int } -func BreakByStyles(s string) []string { - return []string{} +func FindStyleBlocks(s string) []StyleBlock { + items := []StyleBlock{} + return items } func FindStylePositions(s string) []int { diff --git a/style_parser_test.go b/style_parser_test.go index d3088d2..776002c 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,7 +1,6 @@ package termui import ( - "fmt" "strings" "testing" ) @@ -22,22 +21,20 @@ func TestFindStylePositions(t *testing.T) { } } -func TestBreakByStylesComplex(t *testing.T) { - items := BreakByStyles("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") - if len(items) != 10 { +func TestFindStyleBlocks(t *testing.T) { + items := FindStyleBlocks("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + if len(items) != 3 { t.Fatal("wrong length", len(items)) } - text := strings.Join(items, " ") - if text != "test blue fg:blue,bg:white,mod:bold and red fg:red and maybe even foo bg:red !" { - t.Fatal("wrong text", text) + if items[0].Start != 5 && items[0].End != 28 { + t.Fatal("wrong index", items[0]) + } + if items[1].Start != 34 && items[1].End != 46 { + t.Fatal("wrong index", items[1]) + } + if items[2].Start != 63 && items[2].End != 75 { + t.Fatal("wrong index", items[2]) } -} -func TestBreakByStylesSimpler(t *testing.T) { - items := BreakByStyles("[blue](fg:blue) [1]") - // [blue](fg:blue) [1] - // 012345678901234 - // 0-14, rest - fmt.Println(items, len(items)) } func TestParseStyles(t *testing.T) { From 33fef6cb9446795a0802380b7462e30a40aef5a1 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 13:32:59 -0800 Subject: [PATCH 21/29] TestFindStyleBlocks is working --- style_parser.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/style_parser.go b/style_parser.go index 2854c00..42ae333 100644 --- a/style_parser.go +++ b/style_parser.go @@ -84,8 +84,36 @@ type StyleBlock struct { End int } +func findStartEndOfStyle(pos int, runes []rune) StyleBlock { + current := pos + sb := StyleBlock{0, 0} + for { + current-- + if runes[current] == tokenBeginStyledText { + sb.Start = current + break + } + } + current = pos + for { + current++ + if runes[current] == tokenEndStyle { + sb.End = current + break + } + } + return sb +} + func FindStyleBlocks(s string) []StyleBlock { items := []StyleBlock{} + runes := []rune(s) + + positions := FindStylePositions(s) + for _, pos := range positions { + sb := findStartEndOfStyle(pos, runes) + items = append(items, sb) + } return items } From 21dc21d403dfdd640fbd7d4a3ace065f3656f001 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 13:46:07 -0800 Subject: [PATCH 22/29] start of TestBreakBlocksIntoStrings --- style_parser.go | 12 ++++++++++++ style_parser_test.go | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/style_parser.go b/style_parser.go index 42ae333..eb6d7d9 100644 --- a/style_parser.go +++ b/style_parser.go @@ -105,6 +105,18 @@ func findStartEndOfStyle(pos int, runes []rune) StyleBlock { return sb } +func BreakBlocksIntoStrings(s string) { + blocks := FindStyleBlocks(s) + fmt.Println(blocks) + //[{5 28} {34 46} {63 75}] + for _, b := range blocks { + } + s[0:4] + s[29:33] + s[47:62] + s[76:77] +} + func FindStyleBlocks(s string) []StyleBlock { items := []StyleBlock{} runes := []rune(s) diff --git a/style_parser_test.go b/style_parser_test.go index 776002c..facb85a 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -5,6 +5,10 @@ import ( "testing" ) +func TestBreakBlocksIntoStrings(t *testing.T) { + BreakBlocksIntoStrings("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") +} + func TestFindStylePositions(t *testing.T) { items := FindStylePositions("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") if len(items) != 3 { From 80c08963ccdbaf05303d299ae7db1b8461932f2d Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 14:09:43 -0800 Subject: [PATCH 23/29] logic breaking up blocks right --- style_parser.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/style_parser.go b/style_parser.go index eb6d7d9..bb2dbd5 100644 --- a/style_parser.go +++ b/style_parser.go @@ -107,14 +107,16 @@ func findStartEndOfStyle(pos int, runes []rune) StyleBlock { func BreakBlocksIntoStrings(s string) { blocks := FindStyleBlocks(s) - fmt.Println(blocks) - //[{5 28} {34 46} {63 75}] - for _, b := range blocks { + startEnd := len(s) + for i := len(blocks) - 1; i >= 0; i-- { + b := blocks[i] + foo := s[b.End+1 : startEnd] + fmt.Println("|" + foo + "|") + fmt.Println("|" + s[b.Start:b.End+1] + "|") + startEnd = b.Start } - s[0:4] - s[29:33] - s[47:62] - s[76:77] + foo := s[0:startEnd] + fmt.Println("|" + foo + "|") } func FindStyleBlocks(s string) []StyleBlock { From 6cf9178eb342731571aa921ec139890c880eeeae Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 14:14:06 -0800 Subject: [PATCH 24/29] cleanup and printing result in test --- style_parser.go | 19 +++++++++++++------ style_parser_test.go | 4 +++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/style_parser.go b/style_parser.go index bb2dbd5..48c0ff6 100644 --- a/style_parser.go +++ b/style_parser.go @@ -105,18 +105,25 @@ func findStartEndOfStyle(pos int, runes []rune) StyleBlock { return sb } -func BreakBlocksIntoStrings(s string) { +func BreakBlocksIntoStrings(s string) []string { + buff := []string{} blocks := FindStyleBlocks(s) startEnd := len(s) for i := len(blocks) - 1; i >= 0; i-- { b := blocks[i] - foo := s[b.End+1 : startEnd] - fmt.Println("|" + foo + "|") - fmt.Println("|" + s[b.Start:b.End+1] + "|") + item := s[b.End+1 : startEnd] + if item != "" { + buff = append([]string{item}, buff...) + } + item = s[b.Start : b.End+1] + buff = append([]string{item}, buff...) startEnd = b.Start } - foo := s[0:startEnd] - fmt.Println("|" + foo + "|") + item := s[0:startEnd] + if item != "" { + buff = append([]string{item}, buff...) + } + return buff } func FindStyleBlocks(s string) []StyleBlock { diff --git a/style_parser_test.go b/style_parser_test.go index facb85a..2f6261a 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,12 +1,14 @@ package termui import ( + "fmt" "strings" "testing" ) func TestBreakBlocksIntoStrings(t *testing.T) { - BreakBlocksIntoStrings("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + items := BreakBlocksIntoStrings("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + fmt.Println(strings.Join(items, "")) } func TestFindStylePositions(t *testing.T) { From 55ae6181d66df3b7e6b46ba88b8d898d3c8977b6 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Tue, 8 Nov 2022 14:26:28 -0800 Subject: [PATCH 25/29] getting ready for final logic --- style_parser.go | 95 +++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 70 deletions(-) diff --git a/style_parser.go b/style_parser.go index 48c0ff6..29c12e0 100644 --- a/style_parser.go +++ b/style_parser.go @@ -71,14 +71,6 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } -func lookLeftForBracket(s string) int { - return strings.LastIndex(s, "[") -} - -func lookRightForEndStyle(s string) int { - return strings.Index(s, ")") -} - type StyleBlock struct { Start int End int @@ -108,6 +100,9 @@ func findStartEndOfStyle(pos int, runes []rune) StyleBlock { func BreakBlocksIntoStrings(s string) []string { buff := []string{} blocks := FindStyleBlocks(s) + if len(blocks) == 0 { + return buff + } startEnd := len(s) for i := len(blocks) - 1; i >= 0; i-- { b := blocks[i] @@ -160,53 +155,18 @@ func FindStylePositions(s string) []int { } return buff +} - // test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)! +func containsStyle(s string) bool { + return false +} - /* - offset := 0 - for i, token := range tokens { - if i%2 == 0 { - index := lookLeftForBracket(token) - ssp := StyleStringPosition{offset, offset + index, false} - ssps = append(ssps, ssp) - ssp = StyleStringPosition{offset + index, offset + len(token), true} - ssps = append(ssps, ssp) - fmt.Println(i, "even", len(token), index) - } else { - index := lookRightForEndStyle(token) - ssp := StyleStringPosition{offset, offset + index, true} - ssps = append(ssps, ssp) - ssp = StyleStringPosition{offset + index, offset + len(token), false} - ssps = append(ssps, ssp) - fmt.Println(i, "odd", len(token), index) - } - offset += len(token) + 2 - buff = append(buff, token) - } - fmt.Println(ssps) +func extractTextFromBlock(item string) string { + return "hi" +} - - styleString := "" - remainder := tokens[0] - i := 1 - for { - prefix, item := lookLeftForBracket(remainder) - styleString, remainder = lookRightForEndStyle(tokens[i]) - i++ - buff = append(buff, prefix) - buff = append(buff, item) - buff = append(buff, styleString) - if !strings.Contains(remainder, "*") { - buff = append(buff, remainder) - break - } - if i > len(tokens)-1 { - break - } - }*/ - - return buff +func extractStyleFromBlock(item string) string { + return "fg:red" } // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. @@ -216,26 +176,21 @@ func FindStylePositions(s string) []int { func ParseStyles(s string, defaultStyle Style) []Cell { cells := []Cell{} - /* - items := BreakByStyles(s) - if len(items) == 1 { - runes := []rune(s) - for _, _rune := range runes { - cells = append(cells, Cell{_rune, defaultStyle}) - } - return cells - } + items := BreakBlocksIntoStrings(s) + if len(items) == 0 { + return RunesToStyledCells([]rune(s), defaultStyle) + } - style := defaultStyle - for i := len(items) - 1; i > -1; i-- { - if containsColorOrMod(items[i]) { - style = readStyle([]rune(items[i]), defaultStyle) - } else { - cells = append(RunesToStyledCells([]rune(items[i]), style), cells...) - style = defaultStyle - } + for _, item := range items { + if containsStyle(item) { + text := extractTextFromBlock(item) + styleText := extractStyleFromBlock(item) + style := readStyle([]rune(styleText), defaultStyle) + cells = append(RunesToStyledCells([]rune(text), style), cells...) + } else { + cells = append(RunesToStyledCells([]rune(item), defaultStyle), cells...) } - */ + } return cells } From 29db86d4f29224b8b3742e939c07ad4b2bfd9667 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Wed, 9 Nov 2022 05:38:01 -0800 Subject: [PATCH 26/29] more cleanup and comments --- style_parser.go | 120 +++++++++---------------------------------- style_parser_test.go | 6 +-- 2 files changed, 27 insertions(+), 99 deletions(-) diff --git a/style_parser.go b/style_parser.go index 29c12e0..9ad98d4 100644 --- a/style_parser.go +++ b/style_parser.go @@ -5,7 +5,6 @@ package termui import ( - "fmt" "strings" ) @@ -22,10 +21,17 @@ const ( tokenBeginStyle = '(' tokenEndStyle = ')' + + tokenStyleKey = "](" ) type parserState uint +type StyleBlock struct { + Start int + End int +} + const ( parserStateDefault parserState = iota parserStateStyleItems @@ -71,11 +77,8 @@ func readStyle(runes []rune, defaultStyle Style) Style { return style } -type StyleBlock struct { - Start int - End int -} - +// this will start at ]( and look backwards to find the [ and forward +// to find the ) and record these Start and End indexes in a StyleBlock func findStartEndOfStyle(pos int, runes []rune) StyleBlock { current := pos sb := StyleBlock{0, 0} @@ -97,9 +100,11 @@ func findStartEndOfStyle(pos int, runes []rune) StyleBlock { return sb } -func BreakBlocksIntoStrings(s string) []string { +// if are string is "foo [thing](style) foo [more](style)" +// this will return "foo ", "[thing](style)", " foo ", "[more](style)" +func breakBlocksIntoStrings(s string) []string { buff := []string{} - blocks := FindStyleBlocks(s) + blocks := findStyleBlocks(s) if len(blocks) == 0 { return buff } @@ -121,11 +126,12 @@ func BreakBlocksIntoStrings(s string) []string { return buff } -func FindStyleBlocks(s string) []StyleBlock { +// loop through positions and make [] of StyleBlocks +func findStyleBlocks(s string) []StyleBlock { items := []StyleBlock{} runes := []rune(s) - positions := FindStylePositions(s) + positions := findStylePositions(s) for _, pos := range positions { sb := findStartEndOfStyle(pos, runes) items = append(items, sb) @@ -133,9 +139,12 @@ func FindStyleBlocks(s string) []StyleBlock { return items } -func FindStylePositions(s string) []int { - fmt.Println(s) - index := strings.Index(s, "](") +// uses tokenStyleKey ]( which tells us we have both a [text] and a (style) +// if are string is "foo [thing](style) foo [more](style)" +// this func will return a list of two ints: the index of the first ]( and +// the index of the next one +func findStylePositions(s string) []int { + index := strings.Index(s, tokenStyleKey) if index == -1 { return []int{} } @@ -148,7 +157,7 @@ func FindStylePositions(s string) []int { buff = append(buff, index+offset) toProcess = toProcess[index+1:] offset += index + 1 - index = strings.Index(toProcess, "](") + index = strings.Index(toProcess, tokenStyleKey) if index == -1 { break } @@ -176,7 +185,7 @@ func extractStyleFromBlock(item string) string { func ParseStyles(s string, defaultStyle Style) []Cell { cells := []Cell{} - items := BreakBlocksIntoStrings(s) + items := breakBlocksIntoStrings(s) if len(items) == 0 { return RunesToStyledCells([]rune(s), defaultStyle) } @@ -193,84 +202,3 @@ func ParseStyles(s string, defaultStyle Style) []Cell { } return cells } - -func ParseStyles2(s string, defaultStyle Style) []Cell { - cells := []Cell{} - runes := []rune(s) - state := parserStateDefault - styledText := []rune{} - styleItems := []rune{} - squareCount := 0 - - reset := func() { - styledText = []rune{} - styleItems = []rune{} - state = parserStateDefault - squareCount = 0 - } - - rollback := func() { - cells = append(cells, RunesToStyledCells(styledText, defaultStyle)...) - cells = append(cells, RunesToStyledCells(styleItems, defaultStyle)...) - reset() - } - - // chop first and last runes - chop := func(s []rune) []rune { - return s[1 : len(s)-1] - } - - for i, _rune := range runes { - switch state { - case parserStateDefault: - if _rune == tokenBeginStyledText { - state = parserStateStyledText - squareCount = 1 - styledText = append(styledText, _rune) - } else { - cells = append(cells, Cell{_rune, defaultStyle}) - } - case parserStateStyledText: - switch { - case squareCount == 0: - switch _rune { - case tokenBeginStyle: - state = parserStateStyleItems - styleItems = append(styleItems, _rune) - default: - rollback() - switch _rune { - case tokenBeginStyledText: - state = parserStateStyledText - squareCount = 1 - styleItems = append(styleItems, _rune) - default: - cells = append(cells, Cell{_rune, defaultStyle}) - } - } - case len(runes) == i+1: - rollback() - styledText = append(styledText, _rune) - case _rune == tokenBeginStyledText: - squareCount++ - styledText = append(styledText, _rune) - case _rune == tokenEndStyledText: - squareCount-- - styledText = append(styledText, _rune) - default: - styledText = append(styledText, _rune) - } - case parserStateStyleItems: - styleItems = append(styleItems, _rune) - if _rune == tokenEndStyle { - style := readStyle(chop(styleItems), defaultStyle) - cells = append(cells, RunesToStyledCells(chop(styledText), style)...) - reset() - } else if len(runes) == i+1 { - rollback() - } - } - } - - return cells -} diff --git a/style_parser_test.go b/style_parser_test.go index 2f6261a..d9acb60 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -7,12 +7,12 @@ import ( ) func TestBreakBlocksIntoStrings(t *testing.T) { - items := BreakBlocksIntoStrings("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + items := breakBlocksIntoStrings("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") fmt.Println(strings.Join(items, "")) } func TestFindStylePositions(t *testing.T) { - items := FindStylePositions("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + items := findStylePositions("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") if len(items) != 3 { t.Fatal("wrong length", len(items)) } @@ -28,7 +28,7 @@ func TestFindStylePositions(t *testing.T) { } func TestFindStyleBlocks(t *testing.T) { - items := FindStyleBlocks("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") + items := findStyleBlocks("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") if len(items) != 3 { t.Fatal("wrong length", len(items)) } From 238057237be5194391df789389c63643f13e7668 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Wed, 9 Nov 2022 05:46:13 -0800 Subject: [PATCH 27/29] adding containsStyle func --- style_parser.go | 6 ++++++ style_parser_test.go | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/style_parser.go b/style_parser.go index 9ad98d4..08104a1 100644 --- a/style_parser.go +++ b/style_parser.go @@ -167,6 +167,12 @@ func findStylePositions(s string) []int { } func containsStyle(s string) bool { + if strings.HasPrefix(s, string(tokenBeginStyledText)) && + strings.HasSuffix(s, string(tokenEndStyle)) && + strings.Contains(s, string(tokenEndStyledText)) && + strings.Contains(s, string(tokenBeginStyle)) { + return true + } return false } diff --git a/style_parser_test.go b/style_parser_test.go index d9acb60..150073a 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,14 +1,15 @@ package termui import ( - "fmt" "strings" "testing" ) func TestBreakBlocksIntoStrings(t *testing.T) { items := breakBlocksIntoStrings("test [blue](fg:blue,mod:bold) and [red](fg:red) and maybe even [foo](bg:red)!") - fmt.Println(strings.Join(items, "")) + if len(items) != 7 { + t.Fatal("wrong length", len(items)) + } } func TestFindStylePositions(t *testing.T) { From ecf49517b13722e3b8f0081f90367107b84a0cd4 Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Wed, 9 Nov 2022 05:55:44 -0800 Subject: [PATCH 28/29] all tests passing --- style_parser.go | 14 ++++++++++---- style_parser_test.go | 8 ++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/style_parser.go b/style_parser.go index 08104a1..ed774a5 100644 --- a/style_parser.go +++ b/style_parser.go @@ -5,6 +5,7 @@ package termui import ( + "fmt" "strings" ) @@ -176,12 +177,16 @@ func containsStyle(s string) bool { return false } +// [text](style) will return text func extractTextFromBlock(item string) string { - return "hi" + index := strings.Index(item, string(tokenEndStyledText)) + return item[1:index] } +// [text](style) will return style func extractStyleFromBlock(item string) string { - return "fg:red" + index := strings.Index(item, string(tokenBeginStyle)) + return item[index+1 : len(item)-1] } // ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling. @@ -200,10 +205,11 @@ func ParseStyles(s string, defaultStyle Style) []Cell { if containsStyle(item) { text := extractTextFromBlock(item) styleText := extractStyleFromBlock(item) + fmt.Println("|" + text + "|" + styleText + "|") style := readStyle([]rune(styleText), defaultStyle) - cells = append(RunesToStyledCells([]rune(text), style), cells...) + cells = append(cells, RunesToStyledCells([]rune(text), style)...) } else { - cells = append(RunesToStyledCells([]rune(item), defaultStyle), cells...) + cells = append(cells, RunesToStyledCells([]rune(item), defaultStyle)...) } } return cells diff --git a/style_parser_test.go b/style_parser_test.go index 150073a..0c62d89 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,6 +1,7 @@ package termui import ( + "fmt" "strings" "testing" ) @@ -50,9 +51,12 @@ func TestParseStyles(t *testing.T) { if len(cells) != 17 { t.Fatal("wrong length", len(cells)) } + text := textFromCells(cells) + fmt.Println(text) + fmt.Println(cells) for i := 0; i < 5; i++ { if cells[i].Style.Fg != ColorWhite { - t.Fatal("wrong fg color", cells[i]) + t.Fatal("wrong fg color", cells[i], i) } if cells[i].Style.Bg != ColorClear { t.Fatal("wrong bg color", cells[i]) @@ -73,7 +77,7 @@ func TestParseStyles(t *testing.T) { } } - text := textFromCells(cells) + text = textFromCells(cells) if text != "test blue and red" { t.Fatal("wrong text", text) } From a7d7cdbff3eaaa54d3f7002703be9959076813bb Mon Sep 17 00:00:00 2001 From: Andrew Arrow Date: Wed, 9 Nov 2022 05:56:36 -0800 Subject: [PATCH 29/29] removing printlns --- style_parser.go | 2 -- style_parser_test.go | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/style_parser.go b/style_parser.go index ed774a5..fd8214b 100644 --- a/style_parser.go +++ b/style_parser.go @@ -5,7 +5,6 @@ package termui import ( - "fmt" "strings" ) @@ -205,7 +204,6 @@ func ParseStyles(s string, defaultStyle Style) []Cell { if containsStyle(item) { text := extractTextFromBlock(item) styleText := extractStyleFromBlock(item) - fmt.Println("|" + text + "|" + styleText + "|") style := readStyle([]rune(styleText), defaultStyle) cells = append(cells, RunesToStyledCells([]rune(text), style)...) } else { diff --git a/style_parser_test.go b/style_parser_test.go index 0c62d89..ce2dc29 100644 --- a/style_parser_test.go +++ b/style_parser_test.go @@ -1,7 +1,6 @@ package termui import ( - "fmt" "strings" "testing" ) @@ -51,9 +50,6 @@ func TestParseStyles(t *testing.T) { if len(cells) != 17 { t.Fatal("wrong length", len(cells)) } - text := textFromCells(cells) - fmt.Println(text) - fmt.Println(cells) for i := 0; i < 5; i++ { if cells[i].Style.Fg != ColorWhite { t.Fatal("wrong fg color", cells[i], i) @@ -77,7 +73,7 @@ func TestParseStyles(t *testing.T) { } } - text = textFromCells(cells) + text := textFromCells(cells) if text != "test blue and red" { t.Fatal("wrong text", text) }