mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 06:01:52 +08:00
[mac] migrated colour code
This commit is contained in:
parent
15cd325034
commit
616ecabb41
66
v2/pkg/menu/colours/colours.go
Normal file
66
v2/pkg/menu/colours/colours.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
_ "embed"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Rgb struct {
|
||||||
|
R uint8 `json:"r"`
|
||||||
|
G uint8 `json:"g"`
|
||||||
|
B uint8 `json:"b"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hsl struct {
|
||||||
|
H float64 `json:"h"`
|
||||||
|
S float64 `json:"s"`
|
||||||
|
L float64 `json:"l"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InputCol struct {
|
||||||
|
Colorid uint8 `json:"colorId"`
|
||||||
|
Hexstring string `json:"hexString"`
|
||||||
|
Rgb Rgb `json:"rgb"`
|
||||||
|
Hsl Hsl `json:"hsl"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:embed gen.tmpl
|
||||||
|
var Template string
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
var Cols []InputCol
|
||||||
|
|
||||||
|
resp, err := http.Get("https://jonasjacek.github.io/colors/data.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(data, &Cols)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := template.New("cols").Parse(Template)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
err = t.Execute(&buffer, Cols)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
os.WriteFile(filepath.Join("..", "cols.go"), buffer.Bytes(), 0755)
|
||||||
|
}
|
29
v2/pkg/menu/colours/gen.tmpl
Normal file
29
v2/pkg/menu/colours/gen.tmpl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package menu
|
||||||
|
|
||||||
|
type Rgb struct {
|
||||||
|
R uint8 `json:"r"`
|
||||||
|
G uint8 `json:"g"`
|
||||||
|
B uint8 `json:"b"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hsl struct {
|
||||||
|
H float64 `json:"h"`
|
||||||
|
S float64 `json:"s"`
|
||||||
|
L float64 `json:"l"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Col struct {
|
||||||
|
Hex string `json:"hex"`
|
||||||
|
Rgb Rgb `json:"rgb"`
|
||||||
|
Hsl Hsl `json:"hsl"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var Cols = []*Col{ {{range $col := .}}
|
||||||
|
{
|
||||||
|
Hex: "{{.Hexstring}}",
|
||||||
|
Rgb: Rgb{ {{.Rgb.R}}, {{.Rgb.G}}, {{.Rgb.B}} },
|
||||||
|
Hsl: Hsl{ {{.Hsl.H}}, {{.Hsl.S}}, {{.Hsl.L}} },
|
||||||
|
Name: "{{.Name}}",
|
||||||
|
},{{end}}
|
||||||
|
}
|
1559
v2/pkg/menu/cols.go
Executable file
1559
v2/pkg/menu/cols.go
Executable file
File diff suppressed because it is too large
Load Diff
256
v2/pkg/menu/styledlabel.go
Normal file
256
v2/pkg/menu/styledlabel.go
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
package menu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TextStyle int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Bold TextStyle = 1 << 0
|
||||||
|
Faint TextStyle = 1 << 1
|
||||||
|
Italic TextStyle = 1 << 2
|
||||||
|
Blinking TextStyle = 1 << 3
|
||||||
|
Inversed TextStyle = 1 << 4
|
||||||
|
Invisible TextStyle = 1 << 5
|
||||||
|
Underlined TextStyle = 1 << 6
|
||||||
|
Strikethrough TextStyle = 1 << 7
|
||||||
|
)
|
||||||
|
|
||||||
|
type StyledText struct {
|
||||||
|
Label string
|
||||||
|
FgCol *Col
|
||||||
|
BgCol *Col
|
||||||
|
Style TextStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StyledText) Bold() bool {
|
||||||
|
return s.Style&Bold == Bold
|
||||||
|
}
|
||||||
|
func (s *StyledText) Faint() bool {
|
||||||
|
return s.Style&Faint == Faint
|
||||||
|
}
|
||||||
|
func (s *StyledText) Italic() bool {
|
||||||
|
return s.Style&Italic == Italic
|
||||||
|
}
|
||||||
|
func (s *StyledText) Blinking() bool {
|
||||||
|
return s.Style&Blinking == Blinking
|
||||||
|
}
|
||||||
|
func (s *StyledText) Inversed() bool {
|
||||||
|
return s.Style&Inversed == Inversed
|
||||||
|
}
|
||||||
|
func (s *StyledText) Invisible() bool {
|
||||||
|
return s.Style&Invisible == Invisible
|
||||||
|
}
|
||||||
|
func (s *StyledText) Underlined() bool {
|
||||||
|
return s.Style&Underlined == Underlined
|
||||||
|
}
|
||||||
|
func (s *StyledText) Strikethrough() bool {
|
||||||
|
return s.Style&Strikethrough == Strikethrough
|
||||||
|
}
|
||||||
|
|
||||||
|
var ansiColorMap = map[string]map[string]*Col{
|
||||||
|
"Normal": {
|
||||||
|
"30": Cols[0],
|
||||||
|
"31": Cols[1],
|
||||||
|
"32": Cols[2],
|
||||||
|
"33": Cols[3],
|
||||||
|
"34": Cols[4],
|
||||||
|
"35": Cols[5],
|
||||||
|
"36": Cols[6],
|
||||||
|
"37": Cols[7],
|
||||||
|
},
|
||||||
|
"Bold": {
|
||||||
|
"30": Cols[8],
|
||||||
|
"31": Cols[9],
|
||||||
|
"32": Cols[10],
|
||||||
|
"33": Cols[11],
|
||||||
|
"34": Cols[12],
|
||||||
|
"35": Cols[13],
|
||||||
|
"36": Cols[14],
|
||||||
|
"37": Cols[15],
|
||||||
|
},
|
||||||
|
"Faint": {
|
||||||
|
"30": Cols[0],
|
||||||
|
"31": Cols[1],
|
||||||
|
"32": Cols[2],
|
||||||
|
"33": Cols[3],
|
||||||
|
"34": Cols[4],
|
||||||
|
"35": Cols[5],
|
||||||
|
"36": Cols[6],
|
||||||
|
"37": Cols[7],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseANSI(input string) ([]*StyledText, error) {
|
||||||
|
var result []*StyledText
|
||||||
|
invalid := fmt.Errorf("invalid ansi string")
|
||||||
|
missingTerminator := fmt.Errorf("missing escape terminator 'm'")
|
||||||
|
invalidTrueColorSequence := fmt.Errorf("invalid TrueColor sequence")
|
||||||
|
invalid256ColSequence := fmt.Errorf("invalid 256 colour sequence")
|
||||||
|
index := 0
|
||||||
|
var currentStyledText *StyledText = &StyledText{}
|
||||||
|
|
||||||
|
if len(input) == 0 {
|
||||||
|
return nil, invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
// Read all chars to next escape code
|
||||||
|
esc := strings.Index(input, "\033[")
|
||||||
|
|
||||||
|
// If no more esc chars, save what's left and return
|
||||||
|
if esc == -1 {
|
||||||
|
text := input[index:]
|
||||||
|
if len(text) > 0 {
|
||||||
|
currentStyledText.Label = text
|
||||||
|
result = append(result, currentStyledText)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
label := input[:esc]
|
||||||
|
if len(label) > 0 {
|
||||||
|
currentStyledText.Label = label
|
||||||
|
result = append(result, currentStyledText)
|
||||||
|
currentStyledText = &StyledText{
|
||||||
|
Label: "",
|
||||||
|
FgCol: currentStyledText.FgCol,
|
||||||
|
BgCol: currentStyledText.BgCol,
|
||||||
|
Style: currentStyledText.Style,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input = input[esc:]
|
||||||
|
// skip
|
||||||
|
input = input[2:]
|
||||||
|
|
||||||
|
// Read in params
|
||||||
|
endesc := strings.Index(input, "m")
|
||||||
|
if endesc == -1 {
|
||||||
|
return nil, missingTerminator
|
||||||
|
}
|
||||||
|
paramText := input[:endesc]
|
||||||
|
input = input[endesc+1:]
|
||||||
|
params := strings.Split(paramText, ";")
|
||||||
|
colourMap := ansiColorMap["Normal"]
|
||||||
|
skip := 0
|
||||||
|
for index, param := range params {
|
||||||
|
if skip > 0 {
|
||||||
|
skip--
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch param {
|
||||||
|
case "0":
|
||||||
|
// Reset styles
|
||||||
|
if len(params) == 1 {
|
||||||
|
if len(currentStyledText.Label) > 0 {
|
||||||
|
result = append(result, currentStyledText)
|
||||||
|
currentStyledText = &StyledText{
|
||||||
|
Label: "",
|
||||||
|
FgCol: currentStyledText.FgCol,
|
||||||
|
BgCol: currentStyledText.BgCol,
|
||||||
|
Style: currentStyledText.Style,
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentStyledText.Style = 0
|
||||||
|
currentStyledText.FgCol = nil
|
||||||
|
currentStyledText.BgCol = nil
|
||||||
|
case "1":
|
||||||
|
// Bold
|
||||||
|
colourMap = ansiColorMap["Bold"]
|
||||||
|
currentStyledText.Style |= Bold
|
||||||
|
case "2":
|
||||||
|
// Dim/Feint
|
||||||
|
colourMap = ansiColorMap["Faint"]
|
||||||
|
currentStyledText.Style |= Faint
|
||||||
|
case "3":
|
||||||
|
// Italic
|
||||||
|
currentStyledText.Style |= Italic
|
||||||
|
case "4":
|
||||||
|
// Underlined
|
||||||
|
currentStyledText.Style |= Underlined
|
||||||
|
case "5":
|
||||||
|
// Blinking
|
||||||
|
currentStyledText.Style |= Blinking
|
||||||
|
case "7":
|
||||||
|
// Inverse
|
||||||
|
currentStyledText.Style |= Inversed
|
||||||
|
case "8":
|
||||||
|
// Invisible
|
||||||
|
currentStyledText.Style |= Invisible
|
||||||
|
case "9":
|
||||||
|
// Strikethrough
|
||||||
|
currentStyledText.Style |= Strikethrough
|
||||||
|
case "30", "31", "32", "33", "34", "35", "36", "37":
|
||||||
|
currentStyledText.FgCol = colourMap[param]
|
||||||
|
case "40", "41", "42", "43", "44", "45", "46", "47":
|
||||||
|
currentStyledText.BgCol = colourMap[param]
|
||||||
|
case "38", "48":
|
||||||
|
if len(params)-index < 2 {
|
||||||
|
return nil, invalid
|
||||||
|
}
|
||||||
|
// 256 colours
|
||||||
|
if params[index+1] == "5" {
|
||||||
|
skip = 2
|
||||||
|
colIndexText := params[index+2]
|
||||||
|
colIndex, err := strconv.Atoi(colIndexText)
|
||||||
|
if err != nil {
|
||||||
|
return nil, invalid256ColSequence
|
||||||
|
}
|
||||||
|
if colIndex < 0 || colIndex > 255 {
|
||||||
|
return nil, invalid256ColSequence
|
||||||
|
}
|
||||||
|
if param == "38" {
|
||||||
|
currentStyledText.FgCol = Cols[colIndex]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentStyledText.BgCol = Cols[colIndex]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// we must have 4 params left
|
||||||
|
if len(params)-index < 4 {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
if params[index+1] != "2" {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
var r, g, b uint8
|
||||||
|
ri, err := strconv.Atoi(params[index+2])
|
||||||
|
if err != nil {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
gi, err := strconv.Atoi(params[index+3])
|
||||||
|
if err != nil {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
bi, err := strconv.Atoi(params[index+4])
|
||||||
|
if err != nil {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
if bi > 255 || gi > 255 || ri > 255 {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
if bi < 0 || gi < 0 || ri < 0 {
|
||||||
|
return nil, invalidTrueColorSequence
|
||||||
|
}
|
||||||
|
r = uint8(ri)
|
||||||
|
g = uint8(gi)
|
||||||
|
b = uint8(bi)
|
||||||
|
skip = 4
|
||||||
|
colvalue := fmt.Sprintf("#%02x%02x%02x", r, g, b)
|
||||||
|
if param == "38" {
|
||||||
|
currentStyledText.FgCol = &Col{Hex: colvalue, Rgb: Rgb{r, g, b}}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentStyledText.BgCol = &Col{Hex: colvalue}
|
||||||
|
default:
|
||||||
|
return nil, invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
197
v2/pkg/menu/styledlabel_test.go
Normal file
197
v2/pkg/menu/styledlabel_test.go
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
package menu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/matryer/is"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseAnsi16SingleColour(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
wantText string
|
||||||
|
wantColor string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"No formatting", "Hello World", "Hello World", "", false},
|
||||||
|
{"Black", "\u001b[0;30mHello World\033[0m", "Hello World", "Black", false},
|
||||||
|
{"Red", "\u001b[0;31mHello World\033[0m", "Hello World", "Maroon", false},
|
||||||
|
{"Green", "\u001b[0;32m\033[0m", "", "Green", false},
|
||||||
|
{"Yellow", "\u001b[0;33m😀\033[0m", "😀", "Olive", false},
|
||||||
|
{"Blue", "\u001b[0;34m123\033[0m", "123", "Navy", false},
|
||||||
|
{"Purple", "\u001b[0;35m👩🏽🔧\u001B[0m", "👩🏽🔧", "Purple", false},
|
||||||
|
{"Cyan", "\033[0;36m😀\033[0m", "😀", "Teal", false},
|
||||||
|
{"White", "\u001b[0;37m[0;37m\033[0m", "[0;37m", "Silver", false},
|
||||||
|
{"Black Bold", "\u001b[1;30mHello World\033[0m", "Hello World", "Grey", false},
|
||||||
|
{"Red Bold", "\u001b[1;31mHello World\033[0m", "Hello World", "Red", false},
|
||||||
|
{"Green Bold", "\u001b[1;32m\033[0m", "", "Lime", false},
|
||||||
|
{"Yellow Bold", "\u001b[1;33m😀\033[0m", "😀", "Yellow", false},
|
||||||
|
{"Blue Bold", "\u001b[1;34m123\033[0m", "123", "Blue", false},
|
||||||
|
{"Purple Bold", "\u001b[1;35m👩🏽🔧\u001B[0m", "👩🏽🔧", "Fuchsia", false},
|
||||||
|
{"Cyan Bold", "\033[1;36m😀\033[0m", "😀", "Aqua", false},
|
||||||
|
{"White Bold", "\u001b[1;37m[0;37m\033[0m", "[0;37m", "White", false},
|
||||||
|
{"Blank", "", "", "", true},
|
||||||
|
{"Emoji", "😀👩🏽🔧", "😀👩🏽🔧", "", false},
|
||||||
|
{"Spaces", " ", " ", "", false},
|
||||||
|
{"Bad code", "\u001b[1 ", "", "", true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := ParseANSI(tt.input)
|
||||||
|
is.Equal(err != nil, tt.wantErr)
|
||||||
|
expectedLength := 1
|
||||||
|
if tt.wantErr {
|
||||||
|
expectedLength = 0
|
||||||
|
}
|
||||||
|
is.Equal(len(got), expectedLength)
|
||||||
|
if expectedLength == 1 {
|
||||||
|
if len(tt.wantColor) > 0 {
|
||||||
|
is.True(got[0].FgCol != nil)
|
||||||
|
is.Equal(got[0].FgCol.Name, tt.wantColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAnsi16MultiColour(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want []*StyledText
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"Black & Red", "\u001B[0;30mHello World\u001B[0m\u001B[0;31mHello World\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Black"}},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Maroon"}},
|
||||||
|
}, false},
|
||||||
|
{"Text then Black & Red", "This is great!\u001B[0;30mHello World\u001B[0m\u001B[0;31mHello World\u001B[0m", []*StyledText{
|
||||||
|
{Label: "This is great!"},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Black"}},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Maroon"}},
|
||||||
|
}, false},
|
||||||
|
{"Text Reset then Black & Red", "This is great!\u001B[0m\u001B[0;30mHello World\u001B[0m\u001B[0;31mHello World\u001B[0m", []*StyledText{
|
||||||
|
{Label: "This is great!"},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Black"}},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Maroon"}},
|
||||||
|
}, false},
|
||||||
|
{"Black & Red no reset", "\u001B[0;30mHello World\u001B[0;31mHello World", []*StyledText{
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Black"}},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Maroon"}},
|
||||||
|
}, false},
|
||||||
|
{"Black,space,Red", "\u001B[0;30mHello World\u001B[0m \u001B[0;31mHello World\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Black"}},
|
||||||
|
{Label: " "},
|
||||||
|
{Label: "Hello World", FgCol: &Col{Name: "Maroon"}},
|
||||||
|
}, false},
|
||||||
|
{"Black,Red,Blue,Green underlined", "\033[4;30mBlack\u001B[0m\u001B[4;31mRed\u001B[0m\u001B[4;34mBlue\u001B[0m\u001B[4;32mGreen\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Black", FgCol: &Col{Name: "Black"}, Style: Underlined},
|
||||||
|
{Label: "Red", FgCol: &Col{Name: "Maroon"}, Style: Underlined},
|
||||||
|
{Label: "Blue", FgCol: &Col{Name: "Navy"}, Style: Underlined},
|
||||||
|
{Label: "Green", FgCol: &Col{Name: "Green"}, Style: Underlined},
|
||||||
|
}, false},
|
||||||
|
{"Black,Red,Blue,Green bold", "\033[1;30mBlack\u001B[0m\u001B[1;31mRed\u001B[0m\u001B[1;34mBlue\u001B[0m\u001B[1;32mGreen\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Black", FgCol: &Col{Name: "Grey"}, Style: Bold},
|
||||||
|
{Label: "Red", FgCol: &Col{Name: "Red"}, Style: Bold},
|
||||||
|
{Label: "Blue", FgCol: &Col{Name: "Blue"}, Style: Bold},
|
||||||
|
{Label: "Green", FgCol: &Col{Name: "Lime"}, Style: Bold},
|
||||||
|
}, false},
|
||||||
|
{"Green Feint & Yellow Italic", "\u001B[2;32m👩🏽🔧\u001B[0m\u001B[0;3;33m👩🏽🔧\u001B[0m", []*StyledText{
|
||||||
|
{Label: "👩🏽🔧", FgCol: &Col{Name: "Green"}, Style: Faint},
|
||||||
|
{Label: "👩🏽🔧", FgCol: &Col{Name: "Olive"}, Style: Italic},
|
||||||
|
}, false},
|
||||||
|
{"Green Blinking & Yellow Inversed", "\u001B[5;32m👩🏽🔧\u001B[0m\u001B[0;7;33m👩🏽🔧\u001B[0m", []*StyledText{
|
||||||
|
{Label: "👩🏽🔧", FgCol: &Col{Name: "Green"}, Style: Blinking},
|
||||||
|
{Label: "👩🏽🔧", FgCol: &Col{Name: "Olive"}, Style: Inversed},
|
||||||
|
}, false},
|
||||||
|
{"Green Invisible & Yellow Invisible & Strikethrough", "\u001B[8;32m👩🏽🔧\u001B[0m\u001B[9;33m👩🏽🔧\u001B[0m", []*StyledText{
|
||||||
|
{Label: "👩🏽🔧", FgCol: &Col{Name: "Green"}, Style: Invisible},
|
||||||
|
{Label: "👩🏽🔧", FgCol: &Col{Name: "Olive"}, Style: Invisible | Strikethrough},
|
||||||
|
}, false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := ParseANSI(tt.input)
|
||||||
|
is.Equal(err != nil, tt.wantErr)
|
||||||
|
for index, w := range tt.want {
|
||||||
|
is.Equal(got[index].Label, w.Label)
|
||||||
|
if w.FgCol != nil {
|
||||||
|
is.Equal(got[index].FgCol.Name, w.FgCol.Name)
|
||||||
|
}
|
||||||
|
is.Equal(got[index].Style, w.Style)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAnsi256(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want []*StyledText
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"Grey93 & DarkViolet", "\u001B[38;5;255mGrey93\u001B[0m\u001B[38;5;128mDarkViolet\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Grey93", FgCol: &Col{Name: "Grey93"}},
|
||||||
|
{Label: "DarkViolet", FgCol: &Col{Name: "DarkViolet"}},
|
||||||
|
}, false},
|
||||||
|
{"Grey93 Bold & DarkViolet Italic", "\u001B[0;1;38;5;255mGrey93\u001B[0m\u001B[0;3;38;5;128mDarkViolet\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Grey93", FgCol: &Col{Name: "Grey93"}, Style: Bold},
|
||||||
|
{Label: "DarkViolet", FgCol: &Col{Name: "DarkViolet"}, Style: Italic},
|
||||||
|
}, false},
|
||||||
|
{"Grey93 Bold & DarkViolet Italic", "\u001B[0;1;38;5;256mGrey93\u001B[0m", nil, true},
|
||||||
|
{"Grey93 Bold & DarkViolet Italic", "\u001B[0;1;38;5;-1mGrey93\u001B[0m", nil, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := ParseANSI(tt.input)
|
||||||
|
is.Equal(err != nil, tt.wantErr)
|
||||||
|
for index, w := range tt.want {
|
||||||
|
is.Equal(got[index].Label, w.Label)
|
||||||
|
if w.FgCol != nil {
|
||||||
|
is.Equal(got[index].FgCol.Name, w.FgCol.Name)
|
||||||
|
}
|
||||||
|
is.Equal(got[index].Style, w.Style)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAnsiTrueColor(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want []*StyledText
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"Red", "\u001B[38;2;255;0;0mRed\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Red", FgCol: &Col{Rgb: Rgb{255, 0, 0}, Hex: "#ff0000"}},
|
||||||
|
}, false},
|
||||||
|
{"Red, text, Green", "\u001B[38;2;255;0;0mRed\u001B[0mI am plain text\u001B[38;2;0;255;0mGreen\u001B[0m", []*StyledText{
|
||||||
|
{Label: "Red", FgCol: &Col{Rgb: Rgb{255, 0, 0}, Hex: "#ff0000"}},
|
||||||
|
{Label: "I am plain text"},
|
||||||
|
{Label: "Green", FgCol: &Col{Rgb: Rgb{0, 255, 0}, Hex: "#00ff00"}},
|
||||||
|
}, false},
|
||||||
|
{"Bad 1", "\u001B[38;2;256;0;0mRed\u001B[0m", nil, true},
|
||||||
|
{"Bad 2", "\u001B[38;2;-1;0;0mRed\u001B[0m", nil, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := ParseANSI(tt.input)
|
||||||
|
is.Equal(err != nil, tt.wantErr)
|
||||||
|
for index, w := range tt.want {
|
||||||
|
is.Equal(got[index].Label, w.Label)
|
||||||
|
if w.FgCol != nil {
|
||||||
|
is.Equal(got[index].FgCol.Hex, w.FgCol.Hex)
|
||||||
|
is.Equal(got[index].FgCol.Rgb, w.FgCol.Rgb)
|
||||||
|
}
|
||||||
|
is.Equal(got[index].Style, w.Style)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user