You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.2 KiB
79 lines
1.2 KiB
package formatter
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"regexp"
|
|
|
|
"gitoa.ru/go-4devs/console/output/style"
|
|
)
|
|
|
|
//nolint: gochecknoglobals
|
|
var re = regexp.MustCompile(`<(([a-z][^<>]+)|/([a-z][^<>]+)?)>`)
|
|
|
|
func WithStyle(styles func(string) (style.Style, error)) func(*Formatter) {
|
|
return func(f *Formatter) {
|
|
f.styles = styles
|
|
}
|
|
}
|
|
|
|
func New(opts ...func(*Formatter)) *Formatter {
|
|
f := &Formatter{
|
|
styles: style.Find,
|
|
}
|
|
|
|
for _, opt := range opts {
|
|
opt(f)
|
|
}
|
|
|
|
return f
|
|
}
|
|
|
|
type Formatter struct {
|
|
styles func(string) (style.Style, error)
|
|
}
|
|
|
|
func (a *Formatter) Format(ctx context.Context, msg string) string {
|
|
var (
|
|
out bytes.Buffer
|
|
cur int
|
|
)
|
|
|
|
for _, idx := range re.FindAllStringIndex(msg, -1) {
|
|
tag := msg[idx[0]+1 : idx[1]-1]
|
|
|
|
if cur < idx[0] {
|
|
out.WriteString(msg[cur:idx[0]])
|
|
}
|
|
|
|
var (
|
|
st style.Style
|
|
err error
|
|
)
|
|
|
|
switch {
|
|
case tag[0:1] == "/":
|
|
st, err = a.styles(tag[1:])
|
|
if err == nil {
|
|
out.WriteString(st.Set(style.ActionUnset))
|
|
}
|
|
default:
|
|
st, err = a.styles(tag)
|
|
if err == nil {
|
|
out.WriteString(st.Set(style.ActionSet))
|
|
}
|
|
}
|
|
|
|
if err != nil {
|
|
cur = idx[0]
|
|
} else {
|
|
cur = idx[1]
|
|
}
|
|
}
|
|
|
|
if len(msg) > cur {
|
|
out.WriteString(msg[cur:])
|
|
}
|
|
|
|
return out.String()
|
|
}
|
|
|