2015-04-01 15:40:22 -06:00
|
|
|
package termui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TextRender adds common methods for rendering a text on screeen.
|
|
|
|
type TextRender interface {
|
|
|
|
NormalizedText(text string) string
|
2015-04-03 06:10:33 -06:00
|
|
|
RenderSequence(text string, lastColor, background Attribute) RenderedSequence
|
2015-04-01 15:40:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
2015-04-03 06:10:33 -06:00
|
|
|
return r.RenderSequence(text, 0, 0).NormalizedText
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
RenderSequence renders the sequence `text` using a markdown-like syntax:
|
|
|
|
`[hello](red) world` will become: `hello world` where hello is red.
|
|
|
|
|
|
|
|
You may also specify other attributes such as bold text:
|
|
|
|
`[foo](YELLOW, BOLD)` will become `foo` in yellow, bold text.
|
|
|
|
|
2015-04-01 15:40:22 -06:00
|
|
|
|
2015-04-03 06:10:33 -06:00
|
|
|
For all available combinations, colors, and attribute, see: `StringToAttribute`.
|
2015-04-01 15:40:22 -06:00
|
|
|
|
2015-04-03 06:10:33 -06:00
|
|
|
This method returns a RenderedSequence
|
|
|
|
*/
|
|
|
|
func (r MarkdownTextRenderer) RenderSequence(text string, lastColor, background Attribute) RenderedSequence {
|
|
|
|
getMatch := func(s string) []int {
|
|
|
|
return markdownPattern.FindStringSubmatchIndex(strings.ToLower(s))
|
2015-04-01 15:40:22 -06:00
|
|
|
}
|
|
|
|
|
2015-04-03 06:10:33 -06:00
|
|
|
var sequences []ColorSubsequence
|
|
|
|
for match := getMatch(text); match != nil; match = getMatch(text) {
|
|
|
|
start, end := match[0], match[1]
|
|
|
|
colorStart, colorEnd := match[4], match[5]
|
|
|
|
contentStart, contentEnd := match[2], match[3]
|
|
|
|
|
|
|
|
color := strings.ToUpper(text[colorStart:colorEnd])
|
|
|
|
content := text[contentStart:contentEnd]
|
|
|
|
theSequence := ColorSubsequence{color, contentStart - 1, contentEnd - 1}
|
|
|
|
|
|
|
|
sequences = append(sequences, theSequence)
|
|
|
|
text = text[:start] + content + text[end:]
|
|
|
|
}
|
|
|
|
|
|
|
|
return RenderedSequence{text, lastColor, background, sequences}
|
2015-04-01 15:40:22 -06:00
|
|
|
}
|
|
|
|
|
2015-04-03 06:10:33 -06:00
|
|
|
// RenderedSequence is a string sequence that is capable of returning the
|
2015-04-01 15:40:22 -06:00
|
|
|
// Buffer used by termui for displaying the colorful string.
|
2015-04-03 06:10:33 -06:00
|
|
|
type RenderedSequence struct {
|
2015-04-01 15:40:22 -06:00
|
|
|
NormalizedText string
|
|
|
|
LastColor Attribute
|
|
|
|
BackgroundColor Attribute
|
2015-04-03 06:10:33 -06:00
|
|
|
Sequences []ColorSubsequence
|
|
|
|
}
|
2015-04-01 15:40:22 -06:00
|
|
|
|
2015-04-03 06:10:33 -06:00
|
|
|
// A ColorSubsequence represents a color for the given text span.
|
|
|
|
type ColorSubsequence struct {
|
|
|
|
Color string // TODO: use attribute
|
|
|
|
Start int
|
|
|
|
End int
|
2015-04-01 15:40:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Buffer returns the colorful formatted buffer and the last color that was
|
|
|
|
// used.
|
2015-04-03 06:10:33 -06:00
|
|
|
func (s *RenderedSequence) Buffer(x, y int) ([]Point, Attribute) {
|
2015-04-01 15:40:22 -06:00
|
|
|
return nil, s.LastColor
|
|
|
|
}
|