diff --git a/helper_test.go b/helper_test.go index 82967dc..86d2a8e 100644 --- a/helper_test.go +++ b/helper_test.go @@ -5,8 +5,9 @@ package termui import ( - "fmt" "testing" + + "github.com/stretchr/testify/assert" ) func TestStr2Rune(t *testing.T) { @@ -54,20 +55,11 @@ func TestTrim(t *testing.T) { } } -func assertEqual(t *testing.T, expected, got interface{}, msg ...interface{}) { - baseMsg := fmt.Sprintf("Got %v expected %v", got, expected) - msg = append([]interface{}{baseMsg}, msg...) - - if expected != got { - t.Error(fmt.Sprint(msg...)) - } -} - func TestTrimStrIfAppropriate_NoTrim(t *testing.T) { - assertEqual(t, "hello", TrimStrIfAppropriate("hello", 5)) + assert.Equal(t, "hello", TrimStrIfAppropriate("hello", 5)) } func TestTrimStrIfAppropriate(t *testing.T) { - assertEqual(t, "hel…", TrimStrIfAppropriate("hello", 4)) - assertEqual(t, "h…", TrimStrIfAppropriate("hello", 2)) + assert.Equal(t, "hel…", TrimStrIfAppropriate("hello", 4)) + assert.Equal(t, "h…", TrimStrIfAppropriate("hello", 2)) } diff --git a/list.go b/list.go index 0640932..bfec8d4 100644 --- a/list.go +++ b/list.go @@ -83,14 +83,13 @@ func (l *List) Buffer() []Point { } for i, v := range trimItems { rs := trimStr2Runes(v, l.innerWidth) - j := 0 + for _, vv := range rs { w := charWidth(vv) p := Point{} p.X = l.innerX + j p.Y = l.innerY + i - p.Ch = vv p.Bg = l.ItemBgColor p.Fg = l.ItemFgColor diff --git a/textRender.go b/textRender.go new file mode 100644 index 0000000..69c791a --- /dev/null +++ b/textRender.go @@ -0,0 +1,82 @@ +package termui + +import ( + "regexp" + "strings" +) + +// TextRender adds common methods for rendering a text on screeen. +type TextRender interface { + NormalizedText(text string) string + RenderSequence(text string, lastColor, background Attribute) RenderedSubsequence +} + +type subSecequence struct { + start int + end int + color Attribute +} + +// MarkdownRegex is used by MarkdownTextRenderer to determine how to format the +// text. +const MarkdownRegex = `(?:\[([[a-z]+)\])\(([a-z\s,]+)\)` + +// unexported because a pattern can't be a constant and we don't want anyone +// messing with the regex. +var markdownPattern = regexp.MustCompile(MarkdownRegex) + +// MarkdownTextRenderer is used for rendering the text with colors using +// markdown-like syntax. +// See: https://github.com/gizak/termui/issues/4#issuecomment-87270635 +type MarkdownTextRenderer struct{} + +// NormalizedText returns the text the user will see (without colors). +// It strips out all formatting option and only preserves plain text. +func (r MarkdownTextRenderer) NormalizedText(text string) string { + lText := strings.ToLower(text) + indexes := markdownPattern.FindAllStringSubmatchIndex(lText, -1) + + // Interate through indexes in reverse order. + for i := len(indexes) - 1; i >= 0; i-- { + theIndex := indexes[i] + start, end := theIndex[0], theIndex[1] + contentStart, contentEnd := theIndex[2], theIndex[3] + + text = text[:start] + text[contentStart:contentEnd] + text[end:] + } + + return text +} + +// RenderedSubsequence is a string sequence that is capable of returning the +// Buffer used by termui for displaying the colorful string. +type RenderedSubsequence struct { + RawText string + NormalizedText string + LastColor Attribute + BackgroundColor Attribute + + sequences subSecequence +} + +// Buffer returns the colorful formatted buffer and the last color that was +// used. +func (s *RenderedSubsequence) Buffer(x, y int) ([]Point, Attribute) { + // var buffer []Point + // dx := 0 + // for _, r := range []rune(s.NormalizedText) { + // p := Point{ + // Ch: r, + // X: x + dx, + // Y: y, + // Fg: Attribute(rand.Intn(8)), + // Bg: background, + // } + // + // buffer = append(buffer, p) + // dx += charWidth(r) + // } + // + // return buffer + return nil, s.LastColor +} diff --git a/textRender_test.go b/textRender_test.go new file mode 100644 index 0000000..3118211 --- /dev/null +++ b/textRender_test.go @@ -0,0 +1,20 @@ +package termui + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMarkdownTextRenderer_NormalizedText(t *testing.T) { + renderer := MarkdownTextRenderer{} + + got := renderer.NormalizedText("[ERROR](red,bold) Something went wrong") + assert.Equal(t, got, "ERROR Something went wrong") + + got = renderer.NormalizedText("[foo](g) hello [bar](green) world") + assert.Equal(t, got, "foo hello bar world") + + got = renderer.NormalizedText("[foo](g) hello [bar]green (world)") + assert.Equal(t, got, "foo hello [bar]green (world)") +}