From d113e1e7e6ab9c42893f1c15e657dc3df1b7fc76 Mon Sep 17 00:00:00 2001 From: Anthony Moutte Date: Wed, 17 Apr 2019 21:24:32 +0200 Subject: [PATCH 1/2] Implement loader, spinner, progress bar --- examples/loader_test.go | 33 ++++++++++++++++++++++++ loader/bar.go | 12 +++++++++ loader/bar/simple.go | 51 +++++++++++++++++++++++++++++++++++++ loader/bar/styles/simple.go | 45 ++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 examples/loader_test.go create mode 100644 loader/bar.go create mode 100644 loader/bar/simple.go create mode 100644 loader/bar/styles/simple.go diff --git a/examples/loader_test.go b/examples/loader_test.go new file mode 100644 index 0000000..d3283ae --- /dev/null +++ b/examples/loader_test.go @@ -0,0 +1,33 @@ +package examples_test + +import ( + "fmt" + "github.com/gol4ng/cli/loader/bar" + "github.com/gol4ng/cli/loader/bar/styles" +) + +func Example_loader_bar(){ + progress := bar.New(10) + + fmt.Println(progress.Render(0)) + fmt.Println(progress.Render(50)) + fmt.Println(progress.Render(100)) + + // Output: + // ░░░░░░░░░░ + // █████▒░░░░ + // ██████████ +} + +func Example_loader_bar_style(){ + progress := bar.NewSimple(10, styles.NewSimple('=', '-', ">")) + + fmt.Println(progress.Render(0)) + fmt.Println(progress.Render(50)) + fmt.Println(progress.Render(100)) + + // Output: + // ---------- + // =====>---- + // ========== +} diff --git a/loader/bar.go b/loader/bar.go new file mode 100644 index 0000000..98985a2 --- /dev/null +++ b/loader/bar.go @@ -0,0 +1,12 @@ +package loader + +type Bar interface { + Render(percent uint) string +} + +type BarStyle interface { + BarChar() rune + EmptyChar() rune + CursorChar() string + CursorLen() uint +} diff --git a/loader/bar/simple.go b/loader/bar/simple.go new file mode 100644 index 0000000..685c503 --- /dev/null +++ b/loader/bar/simple.go @@ -0,0 +1,51 @@ +package bar + +import ( + "strings" + + "github.com/gol4ng/cli/loader" + "github.com/gol4ng/cli/loader/bar/styles" +) + +type simple struct { + loader.BarStyle + length uint +} + +func (d *simple) Render(percent uint) string { + if percent > 100 { + percent = 100 + } + builder := strings.Builder{} + barLen := d.length * percent / 100 + emptyLen := int(d.length) + if percent > 0 { + builder.WriteString(strings.Repeat(string(d.BarStyle.BarChar()), int(barLen))) + emptyLen -= int(barLen) + + if percent < 100 { + cursor := d.BarStyle.CursorChar() + if emptyLen < int(d.BarStyle.CursorLen()) { + cursor = cursor[:emptyLen] + } + builder.WriteString(cursor) + emptyLen -= int(d.BarStyle.CursorLen()) + } + } + if emptyLen > 0 { + builder.WriteString(strings.Repeat(string(d.BarStyle.EmptyChar()), int(emptyLen))) + } + + return builder.String() +} + +func New(length uint) *simple { + return NewSimple(length, styles.New()) +} + +func NewSimple(length uint, style loader.BarStyle) *simple { + return &simple{ + length: length, + BarStyle: style, + } +} diff --git a/loader/bar/styles/simple.go b/loader/bar/styles/simple.go new file mode 100644 index 0000000..a192ccc --- /dev/null +++ b/loader/bar/styles/simple.go @@ -0,0 +1,45 @@ +package styles + +import "unicode/utf8" + +const ( + defaultBar rune = '█' + defaultEmpty = '░' + defaultCursor string = "▒" +) + +type Simple struct { + Bar rune + Empty rune + Cursor string + CursorLength uint +} + +func (d *Simple) BarChar() rune { + return d.Bar +} + +func (d *Simple) EmptyChar() rune { + return d.Empty +} + +func (d *Simple) CursorChar() string { + return d.Cursor +} + +func (d *Simple) CursorLen() uint { + return d.CursorLength +} + +func New() *Simple { + return NewSimple(defaultBar, defaultEmpty, defaultCursor) +} + +func NewSimple(bar rune, empty rune, cursor string) *Simple { + return &Simple{ + Bar: bar, + Empty: empty, + Cursor: cursor, + CursorLength: uint(utf8.RuneCountInString(cursor)), + } +} From 2fc7323fc5a2d65ea6d27f0ccebf103bf6640b40 Mon Sep 17 00:00:00 2001 From: Anthony Moutte Date: Wed, 17 Apr 2019 21:26:01 +0200 Subject: [PATCH 2/2] Alpha version --- ansi.go | 15 ++ builder.go | 36 +++++ examples/ansi_test.go | 37 +++++ examples/loader_test.go | 33 ----- examples/progress_bar_test.go | 130 +++++++++++++++++ examples/progress_test.go | 33 +++++ loader/bar.go | 117 ++++++++++++++- loader/bar/simple.go | 51 ------- loader/bar/styles/simple.go | 45 ------ loader/progress.go | 81 +++++++++++ loader/progress_bar.go | 36 +++++ loader/spinner.go | 37 +++++ loader/style/simple.go | 54 +++++++ sgr.go | 243 +++++++++++++++++++++++++++++++ sgr_test.go | 26 ++++ unicode/block_elements.go | 43 ++++++ unicode/box_drawings.go | 139 ++++++++++++++++++ unicode/braille_pattern.go | 267 ++++++++++++++++++++++++++++++++++ unicode/geometric-shapes.go | 106 ++++++++++++++ 19 files changed, 1396 insertions(+), 133 deletions(-) create mode 100644 ansi.go create mode 100644 builder.go create mode 100644 examples/ansi_test.go delete mode 100644 examples/loader_test.go create mode 100644 examples/progress_bar_test.go create mode 100644 examples/progress_test.go delete mode 100644 loader/bar/simple.go delete mode 100644 loader/bar/styles/simple.go create mode 100644 loader/progress.go create mode 100644 loader/progress_bar.go create mode 100644 loader/spinner.go create mode 100644 loader/style/simple.go create mode 100644 sgr.go create mode 100644 sgr_test.go create mode 100644 unicode/block_elements.go create mode 100644 unicode/box_drawings.go create mode 100644 unicode/braille_pattern.go create mode 100644 unicode/geometric-shapes.go diff --git a/ansi.go b/ansi.go new file mode 100644 index 0000000..6dd679f --- /dev/null +++ b/ansi.go @@ -0,0 +1,15 @@ +package cli + +// https://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements +const ( + ESC string = "\x1b" + + //Control Sequence Introducer + CSI = ESC + "[" + + //Select Graphic Rendition + SGREnd = "m" + SGRReset = CSI + SGREnd + + SepControlChar = ";" +) diff --git a/builder.go b/builder.go new file mode 100644 index 0000000..c7a88cc --- /dev/null +++ b/builder.go @@ -0,0 +1,36 @@ +package cli + +import "strings" + +type Writer interface { + WriteString(s string) (int, error) +} + +type Buffer interface { + Writer + String() string +} + +type Builder struct { + buffer Buffer +} + +func (c *Builder) WriteString(s string) *Builder { + _, err := c.buffer.WriteString(s) + if err != nil { + panic(err) + } + return c +} + +func (c *Builder) String() string { + return c.buffer.String() +} + +func New(buffer Buffer) *Builder { + return &Builder{buffer: buffer} +} + +func NewStringBuilder() *Builder { + return New(&strings.Builder{}) +} diff --git a/examples/ansi_test.go b/examples/ansi_test.go new file mode 100644 index 0000000..d4bd6b3 --- /dev/null +++ b/examples/ansi_test.go @@ -0,0 +1,37 @@ +package examples_test + +import ( + "github.com/stretchr/testify/assert" + "testing" + + "github.com/gol4ng/cli" +) + +func Test_ansi_sgr(t *testing.T) { + w := cli.NewStringBuilder(). + + // add some content + Write("first content\n"). + + // add some content with style + Write("stylize content\n", cli.Italic, cli.Yellow). + Write("style resetted\n"). + Red("style red\n"). + Bold("style bold\n"). + + // begin style and write content + Style(cli.Underline, cli.Red).WriteString("apply a style\n"). + WriteString("previous style continue until Reset was called or another style apply\n"). + + // new style began + Style(cli.Bold, cli.Blue).WriteString("new style\n") + + // manually reset style + w.Reset().Write("style manually resetted\n") + + assert.Equal( + t, + "first content\n\x1b[m\x1b[3;33mstylize content\n\x1b[mstyle resetted\n\x1b[m\x1b[31mstyle red\n\x1b[m\x1b[1mstyle bold\n\x1b[m\x1b[4;31mapply a style\nprevious style continue until Reset was called or another style apply\n\x1b[1;34mnew style\n\x1b[mstyle manually resetted\n\x1b[m", + w.String(), + ) +} diff --git a/examples/loader_test.go b/examples/loader_test.go deleted file mode 100644 index d3283ae..0000000 --- a/examples/loader_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package examples_test - -import ( - "fmt" - "github.com/gol4ng/cli/loader/bar" - "github.com/gol4ng/cli/loader/bar/styles" -) - -func Example_loader_bar(){ - progress := bar.New(10) - - fmt.Println(progress.Render(0)) - fmt.Println(progress.Render(50)) - fmt.Println(progress.Render(100)) - - // Output: - // ░░░░░░░░░░ - // █████▒░░░░ - // ██████████ -} - -func Example_loader_bar_style(){ - progress := bar.NewSimple(10, styles.NewSimple('=', '-', ">")) - - fmt.Println(progress.Render(0)) - fmt.Println(progress.Render(50)) - fmt.Println(progress.Render(100)) - - // Output: - // ---------- - // =====>---- - // ========== -} diff --git a/examples/progress_bar_test.go b/examples/progress_bar_test.go new file mode 100644 index 0000000..948b283 --- /dev/null +++ b/examples/progress_bar_test.go @@ -0,0 +1,130 @@ +package examples_test + +import ( + "fmt" + "github.com/gol4ng/cli/loader" + "github.com/gol4ng/cli/loader/style" +) + +func Example_progress_bar() { + progress := loader.NewDefaultProgressBar(10, 10) + + fmt.Println(progress.Progress.String(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.SetStep(5), progress) + + fmt.Println(progress.Fill(), progress) + + fmt.Println(progress.SetMax(20), progress) + fmt.Println(progress.SetStep(15), progress) + fmt.Println(progress.SetMax(10), progress) + + // Output: + + // 0/10 ░░░░░░░░░░ + // 1/10 █▒░░░░░░░░ + // 5/10 █████▒░░░░ + // 10/10 ██████████ + // 10/20 █████▒░░░░ + // 15/20 ███████▒░░ + // 10/10 ██████████ +} + +func Example_progress_bar_custom() { + progress := loader.NewProgressBar(10, loader.NewBarRenderer(10, style.NewBarSimple("=", "-", ">"))) + + fmt.Println(progress.Progress.String(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.SetStep(5), progress) + + fmt.Println(progress.Fill(), progress) + + fmt.Println(progress.SetMax(20), progress) + fmt.Println(progress.SetStep(15), progress) + fmt.Println(progress.SetMax(10), progress) + + // Output: + + // 0/10 ---------- + // 1/10 =>-------- + // 5/10 =====>---- + // 10/10 ========== + // 10/20 =====>---- + // 15/20 =======>-- + // 10/10 ========== +} + +func Example_progress_bar_vertical_char() { + progress := loader.NewProgressBar(8, loader.NewSliceBar(loader.VerticalChar)) + + fmt.Println(progress.Progress.String(), progress, "|") + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + + // Output: + // 0/8 | + // 1/8 ▁ + // 2/8 ▂ + // 3/8 ▃ + // 4/8 ▄ + // 5/8 ▅ + // 6/8 ▆ + // 7/8 ▇ + // 8/8 █ +} + +func Example_progress_bar_horizontal_char() { + progress := loader.NewProgressBar(8, loader.NewSliceBar(loader.HorizontalChar)) + + fmt.Println(progress.Progress.String(), progress, "|") + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + + // Output: + // 0/8 | + // 1/8 ▏ + // 2/8 ▎ + // 3/8 ▍ + // 4/8 ▌ + // 5/8 ▋ + // 6/8 ▊ + // 7/8 ▉ + // 8/8 █ +} + +func Example_progress_dot_char() { + progress := loader.NewProgressBar(8, loader.NewSliceBar(loader.DotChar)) + + fmt.Println(progress.Progress.String(), progress, "|") + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + fmt.Println(progress.Increase(), progress) + + // Output: + //0/8 | + //1/8 ⠁ + //2/8 ⠉ + //3/8 ⠋ + //4/8 ⠛ + //5/8 ⠟ + //6/8 ⠿ + //7/8 ⡿ + //8/8 ⣿ +} diff --git a/examples/progress_test.go b/examples/progress_test.go new file mode 100644 index 0000000..ace76d5 --- /dev/null +++ b/examples/progress_test.go @@ -0,0 +1,33 @@ +package examples_test + +import ( + "fmt" + "github.com/gol4ng/cli/loader" +) + +func Example_progress() { + progress := loader.NewProgress(10) + + fmt.Println(progress.Decrease(), progress.Percent()) + fmt.Println(progress.Fill(), progress.Percent()) + fmt.Println(progress.Increase(), progress.Percent()) + + fmt.Println(progress.SetStep(5), progress.Percent()) + fmt.Println(progress.Decrease(), progress.Percent()) + fmt.Println(progress.Reset(), progress.Percent()) + + fmt.Println(progress.SetMax(20), progress.Percent()) + fmt.Println(progress.SetStep(15), progress.Percent()) + fmt.Println(progress.SetMax(10), progress.Percent()) + + // Output: + // 0/10 0 + // 10/10 100 + // 10/10 100 + // 5/10 50 + // 4/10 40 + // 0/10 0 + // 0/20 0 + // 15/20 75 + // 10/10 100 +} diff --git a/loader/bar.go b/loader/bar.go index 98985a2..9673241 100644 --- a/loader/bar.go +++ b/loader/bar.go @@ -1,12 +1,121 @@ package loader -type Bar interface { - Render(percent uint) string +import ( + "strings" + + "github.com/gol4ng/cli" + "github.com/gol4ng/cli/loader/style" + "github.com/gol4ng/cli/unicode" +) + +var VerticalChar = []rune{ + ' ', + unicode.LowerOneEighthBlock, + unicode.LowerOneQuarterBlock, + unicode.LowerThreeEighthsBlock, + unicode.LowerHalfBlock, + unicode.LowerFiveEighthsBlock, + unicode.LowerThreeQuartersBlock, + unicode.LowerSevenEighthsBlock, + unicode.FullBlock, +} + +var HorizontalChar = []rune{ + ' ', + unicode.LeftOneEighthBlock, + unicode.LeftOneQuarterBlock, + unicode.LeftThreeEighthsBlock, + unicode.LeftHalfBlock, + unicode.LeftFiveEighthsBlock, + unicode.LeftThreeQuartersBlock, + unicode.LeftSevenEighthsBlock, + unicode.FullBlock, +} + +var DotChar = []rune{ + ' ', + unicode.BraillePatternDots_1, + unicode.BraillePatternDots_14, + unicode.BraillePatternDots_124, + unicode.BraillePatternDots_1245, + unicode.BraillePatternDots_12345, + unicode.BraillePatternDots_123456, + unicode.BraillePatternDots_1234567, + unicode.BraillePatternDots_12345678, } type BarStyle interface { - BarChar() rune - EmptyChar() rune + BarChar() string + BarLen() uint + EmptyChar() string + EmptyLen() uint CursorChar() string CursorLen() uint } + +type Bar struct { + BarStyle + length uint +} + +func (d *Bar) Render(progress Progress) string { + return d.RenderIn(progress, &strings.Builder{}) +} + +func (d *Bar) RenderIn(progress Progress, buffer cli.Buffer) string { + percent := progress.Percent() + barLen := int(d.length * uint(percent) / 100 * d.BarStyle.BarLen()) + emptyLen := int(d.length * d.BarStyle.EmptyLen()) + if percent > 0 { + buffer.WriteString(strings.Repeat(string(d.BarStyle.BarChar()), barLen)) + emptyLen -= barLen + + if percent < 100 { + cursor := d.BarStyle.CursorChar() + if emptyLen < int(d.BarStyle.CursorLen()) { + cursor = cursor[:emptyLen] + } + buffer.WriteString(cursor) + emptyLen -= int(d.BarStyle.CursorLen()) + } + } + if emptyLen > 0 { + buffer.WriteString(strings.Repeat(string(d.BarStyle.EmptyChar()), int(emptyLen))) + } + + return buffer.String() +} + +func NewDefaultBarRenderer(length uint) *Bar { + return NewBarRenderer(length, style.NewBar()) +} + +func NewBarRenderer(length uint, style BarStyle) *Bar { + return &Bar{ + length: length, + BarStyle: style, + } +} + +type SliceBar struct { + chars []rune +} + +func (d *SliceBar) Render(progress Progress) string { + return d.RenderIn(progress, &strings.Builder{}) +} + +func (d *SliceBar) RenderIn(progress Progress, buffer cli.Buffer) string { + percent := progress.Percent() + threshold := float64(100) / float64(len(d.chars)) + for i := 0; i < len(d.chars); i++ { + if percent < threshold*float64(i+1) { + return string(d.chars[i]) + } + } + return string(d.chars[len(d.chars)-1]) +} + +func NewSliceBar(chars []rune) *SliceBar { + return &SliceBar{chars: chars} +} diff --git a/loader/bar/simple.go b/loader/bar/simple.go deleted file mode 100644 index 685c503..0000000 --- a/loader/bar/simple.go +++ /dev/null @@ -1,51 +0,0 @@ -package bar - -import ( - "strings" - - "github.com/gol4ng/cli/loader" - "github.com/gol4ng/cli/loader/bar/styles" -) - -type simple struct { - loader.BarStyle - length uint -} - -func (d *simple) Render(percent uint) string { - if percent > 100 { - percent = 100 - } - builder := strings.Builder{} - barLen := d.length * percent / 100 - emptyLen := int(d.length) - if percent > 0 { - builder.WriteString(strings.Repeat(string(d.BarStyle.BarChar()), int(barLen))) - emptyLen -= int(barLen) - - if percent < 100 { - cursor := d.BarStyle.CursorChar() - if emptyLen < int(d.BarStyle.CursorLen()) { - cursor = cursor[:emptyLen] - } - builder.WriteString(cursor) - emptyLen -= int(d.BarStyle.CursorLen()) - } - } - if emptyLen > 0 { - builder.WriteString(strings.Repeat(string(d.BarStyle.EmptyChar()), int(emptyLen))) - } - - return builder.String() -} - -func New(length uint) *simple { - return NewSimple(length, styles.New()) -} - -func NewSimple(length uint, style loader.BarStyle) *simple { - return &simple{ - length: length, - BarStyle: style, - } -} diff --git a/loader/bar/styles/simple.go b/loader/bar/styles/simple.go deleted file mode 100644 index a192ccc..0000000 --- a/loader/bar/styles/simple.go +++ /dev/null @@ -1,45 +0,0 @@ -package styles - -import "unicode/utf8" - -const ( - defaultBar rune = '█' - defaultEmpty = '░' - defaultCursor string = "▒" -) - -type Simple struct { - Bar rune - Empty rune - Cursor string - CursorLength uint -} - -func (d *Simple) BarChar() rune { - return d.Bar -} - -func (d *Simple) EmptyChar() rune { - return d.Empty -} - -func (d *Simple) CursorChar() string { - return d.Cursor -} - -func (d *Simple) CursorLen() uint { - return d.CursorLength -} - -func New() *Simple { - return NewSimple(defaultBar, defaultEmpty, defaultCursor) -} - -func NewSimple(bar rune, empty rune, cursor string) *Simple { - return &Simple{ - Bar: bar, - Empty: empty, - Cursor: cursor, - CursorLength: uint(utf8.RuneCountInString(cursor)), - } -} diff --git a/loader/progress.go b/loader/progress.go new file mode 100644 index 0000000..f99c74c --- /dev/null +++ b/loader/progress.go @@ -0,0 +1,81 @@ +package loader + +import ( + "github.com/gol4ng/cli" + "strconv" + "strings" +) + +type ProgressRenderer interface { + Render(progress Progress) string + RenderIn(progress Progress, buffer cli.Buffer) string +} + +type Progress struct { + step uint + max uint +} + +func (p *Progress) GetStep() uint { + return p.step +} + +func (p *Progress) SetStep(step uint) *Progress { + if step > p.max { + step = p.max + } + p.step = step + return p +} + +func (p *Progress) GetMax() uint { + return p.step +} + +func (p *Progress) SetMax(max uint) *Progress { + p.max = max + if p.step > p.max { + p.step = p.max + } + return p +} + +func (p *Progress) Increase() *Progress { + if p.step < p.max { + p.step++ + } + return p +} + +func (p *Progress) Decrease() *Progress { + if p.step > 0 { + p.step-- + } + return p +} + +func (p *Progress) Fill() *Progress { + p.step = p.max + return p +} + +func (p *Progress) Reset() *Progress { + p.step = 0 + return p +} + +func (p *Progress) Percent() float64 { + return float64(p.step) / float64(p.max) * 100 +} + +func (p *Progress) String() string { + b := strings.Builder{} + b.WriteString(strconv.Itoa(int(p.step))) + b.WriteString("/") + b.WriteString(strconv.Itoa(int(p.max))) + return b.String() +} + +func NewProgress(max uint) *Progress { + return &Progress{step: 0, max: max} +} diff --git a/loader/progress_bar.go b/loader/progress_bar.go new file mode 100644 index 0000000..a697f69 --- /dev/null +++ b/loader/progress_bar.go @@ -0,0 +1,36 @@ +package loader + +import ( + "github.com/gol4ng/cli" +) + +type ProgressBar struct { + Progress + renderer ProgressRenderer +} + +func (pb *ProgressBar) Render() string { + return pb.renderer.Render(pb.Progress) +} + +func (pb *ProgressBar) RenderIn(buffer cli.Buffer) string { + return pb.renderer.RenderIn(pb.Progress, buffer) +} + +func (pb *ProgressBar) String() string { + return pb.Render() +} + +func NewDefaultProgressBar(max uint, length uint) *ProgressBar { + return &ProgressBar{ + Progress: *NewProgress(max), + renderer: NewDefaultBarRenderer(length), + } +} + +func NewProgressBar(max uint, renderer ProgressRenderer) *ProgressBar { + return &ProgressBar{ + Progress: *NewProgress(max), + renderer: renderer, + } +} diff --git a/loader/spinner.go b/loader/spinner.go new file mode 100644 index 0000000..e21ebc6 --- /dev/null +++ b/loader/spinner.go @@ -0,0 +1,37 @@ +package loader + +import ( + "github.com/gol4ng/cli/unicode" +) + +var ClockSquare = []rune{ + unicode.WhiteSquareWithUpperRightQuadrant, + unicode.WhiteSquareWithLowerRightQuadrant, + unicode.WhiteSquareWithLowerLeftQuadrant, + unicode.WhiteSquareWithUpperLeftQuadrant, +} + +var Clock = []rune{ + unicode.WhiteCircleWithUpperRightQuadrant, + unicode.WhiteCircleWithLowerRightQuadrant, + unicode.WhiteCircleWithLowerLeftQuadrant, + unicode.WhiteCircleWithUpperLeftQuadrant, +} + +type Spinner struct { + chars []rune + frame uint +} + +func (s *Spinner) String() string { + value := string(s.chars[int(s.frame)%len(s.chars)]) + s.frame++ + return value +} + +func NewCharSpinner(chars []rune) *Spinner { + if len(chars) == 0 { + panic("you must provide chars") + } + return &Spinner{chars: chars, frame: 0} +} diff --git a/loader/style/simple.go b/loader/style/simple.go new file mode 100644 index 0000000..2f0946a --- /dev/null +++ b/loader/style/simple.go @@ -0,0 +1,54 @@ +package style + +import ( + "github.com/gol4ng/cli/unicode" + "unicode/utf8" +) + +type Simple struct { + Bar string + BarLength uint + Empty string + EmptyLength uint + Cursor string + CursorLength uint +} + +func (d *Simple) BarChar() string { + return d.Bar +} + +func (d *Simple) BarLen() uint { + return d.BarLength +} + +func (d *Simple) EmptyChar() string { + return d.Empty +} + +func (d *Simple) EmptyLen() uint { + return d.EmptyLength +} + +func (d *Simple) CursorChar() string { + return d.Cursor +} + +func (d *Simple) CursorLen() uint { + return d.CursorLength +} + +func NewBar() *Simple { + return NewBarSimple(string(unicode.FullBlock), string(unicode.LightShade), string(unicode.MediumShade)) +} + +func NewBarSimple(bar string, empty string, cursor string) *Simple { + return &Simple{ + Bar: bar, + BarLength: uint(utf8.RuneCountInString(bar)), + Empty: empty, + EmptyLength: uint(utf8.RuneCountInString(empty)), + Cursor: cursor, + CursorLength: uint(utf8.RuneCountInString(cursor)), + } +} diff --git a/sgr.go b/sgr.go new file mode 100644 index 0000000..585b648 --- /dev/null +++ b/sgr.go @@ -0,0 +1,243 @@ +package cli + +import ( + "strings" + "unsafe" +) + +type Attribute string + +const ( + Reset = "0" + Bold = "1" + Faint = "2" + Italic = "3" + Underline = "4" + BlinkSlow = "5" + BlinkRapid = "6" + ReverseVideo = "7" + Concealed = "8" + CrossedOut = "9" + + Default = "39" // Default was here for reference + Black = "30" + Red = "31" + Green = "32" + Yellow = "33" + Blue = "34" + Magenta = "35" + Cyan = "36" + White = "37" + HiBlack = "90" + HiRed = "91" + HiGreen = "92" + HiYellow = "93" + HiBlue = "94" + HiMagenta = "95" + HiCyan = "96" + HiWhite = "97" + + BgDefault = "49" // BgDefault was here for reference + BgBlack = "40" + BgRed = "41" + BgGreen = "42" + BgYellow = "43" + BgBlue = "44" + BgMagenta = "45" + BgCyan = "46" + BgWhite = "47" + BgHiBlack = "100" + BgHiRed = "101" + BgHiGreen = "102" + BgHiYellow = "103" + BgHiBlue = "104" + BgHiMagenta = "105" + BgHiCyan = "106" + BgHiWhite = "107" +) + +func (c *Builder) attribute(attributes ...Attribute) *Builder { + return c.WriteString(strings.Join(*(*[]string)(unsafe.Pointer(&attributes)), SepControlChar)) +} + +func (c *Builder) Write(s string, attributes ...Attribute) *Builder { + return c.Style(attributes...).WriteString(s).Reset() +} + +func (c *Builder) Style(attributes ...Attribute) *Builder { + if len(attributes) > 0 { + c. + WriteString(CSI). + attribute(attributes...). + WriteString(SGREnd) + } + return c +} + +func (c *Builder) Reset() *Builder { + return c.WriteString(SGRReset) +} + +func (c *Builder) Bold(s string) *Builder { + return c.Style(Bold).WriteString(s).Reset() +} + +func (c *Builder) Faint(s string) *Builder { + return c.Style(Faint).WriteString(s).Reset() +} + +func (c *Builder) Italic(s string) *Builder { + return c.Style(Italic).WriteString(s).Reset() +} + +func (c *Builder) Underline(s string) *Builder { + return c.Style(Underline).WriteString(s).Reset() +} + +func (c *Builder) BlinkSlow(s string) *Builder { + return c.Style(BlinkSlow).WriteString(s).Reset() +} + +func (c *Builder) BlinkRapid(s string) *Builder { + return c.Style(BlinkRapid).WriteString(s).Reset() +} + +func (c *Builder) ReverseVideo(s string) *Builder { + return c.Style(ReverseVideo).WriteString(s).Reset() +} + +func (c *Builder) Concealed(s string) *Builder { + return c.Style(Concealed).WriteString(s).Reset() +} + +func (c *Builder) CrossedOut(s string) *Builder { + return c.Style(CrossedOut).WriteString(s).Reset() +} + +func (c *Builder) Black(value string) *Builder { + return c.Style(Black).WriteString(value).Reset() +} + +func (c *Builder) Red(value string) *Builder { + return c.Style(Red).WriteString(value).Reset() +} + +func (c *Builder) Green(value string) *Builder { + return c.Style(Green).WriteString(value).Reset() +} + +func (c *Builder) Yellow(value string) *Builder { + return c.Style(Yellow).WriteString(value).Reset() +} + +func (c *Builder) Blue(value string) *Builder { + return c.Style(Blue).WriteString(value).Reset() +} + +func (c *Builder) Magenta(value string) *Builder { + return c.Style(Magenta).WriteString(value).Reset() +} + +func (c *Builder) Cyan(value string) *Builder { + return c.Style(Cyan).WriteString(value).Reset() +} + +func (c *Builder) White(value string) *Builder { + return c.Style(White).WriteString(value).Reset() +} + +func (c *Builder) HiBlack(value string) *Builder { + return c.Style(HiBlack).WriteString(value).Reset() +} + +func (c *Builder) HiRed(value string) *Builder { + return c.Style(HiRed).WriteString(value).Reset() +} + +func (c *Builder) HiGreen(value string) *Builder { + return c.Style(HiGreen).WriteString(value).Reset() +} + +func (c *Builder) HiYellow(value string) *Builder { + return c.Style(HiYellow).WriteString(value).Reset() +} + +func (c *Builder) HiBlue(value string) *Builder { + return c.Style(HiBlue).WriteString(value).Reset() +} + +func (c *Builder) HiMagenta(value string) *Builder { + return c.Style(HiMagenta).WriteString(value).Reset() +} + +func (c *Builder) HiCyan(value string) *Builder { + return c.Style(HiCyan).WriteString(value).Reset() +} + +func (c *Builder) HiWhite(value string) *Builder { + return c.Style(HiWhite).WriteString(value).Reset() +} + +func (c *Builder) BgBlack(value string) *Builder { + return c.Style(BgBlack).WriteString(value).Reset() +} + +func (c *Builder) BgRed(value string) *Builder { + return c.Style(BgRed).WriteString(value).Reset() +} + +func (c *Builder) BgGreen(value string) *Builder { + return c.Style(BgGreen).WriteString(value).Reset() +} + +func (c *Builder) BgYellow(value string) *Builder { + return c.Style(BgYellow).WriteString(value).Reset() +} + +func (c *Builder) BgBlue(value string) *Builder { + return c.Style(BgBlue).WriteString(value).Reset() +} + +func (c *Builder) BgMagenta(value string) *Builder { + return c.Style(BgMagenta).WriteString(value).Reset() +} + +func (c *Builder) BgCyan(value string) *Builder { + return c.Style(BgCyan).WriteString(value).Reset() +} + +func (c *Builder) BgWhite(value string) *Builder { + return c.Style(BgWhite).WriteString(value).Reset() +} + +func (c *Builder) BgHiBlack(value string) *Builder { + return c.Style(BgHiBlack).WriteString(value).Reset() +} + +func (c *Builder) BgHiRed(value string) *Builder { + return c.Style(BgHiRed).WriteString(value).Reset() +} + +func (c *Builder) BgHiGreen(value string) *Builder { + return c.Style(BgHiGreen).WriteString(value).Reset() +} + +func (c *Builder) BgHiYellow(value string) *Builder { + return c.Style(BgHiYellow).WriteString(value).Reset() +} + +func (c *Builder) BgHiBlue(value string) *Builder { + return c.Style(BgHiBlue).WriteString(value).Reset() +} + +func (c *Builder) BgHiMagenta(value string) *Builder { + return c.Style(BgHiMagenta).WriteString(value).Reset() +} + +func (c *Builder) BgHiCyan(value string) *Builder { + return c.Style(BgHiCyan).WriteString(value).Reset() +} + +func (c *Builder) BgHiWhite(value string) *Builder { + return c.Style(BgHiWhite).WriteString(value).Reset() +} diff --git a/sgr_test.go b/sgr_test.go new file mode 100644 index 0000000..754b4d7 --- /dev/null +++ b/sgr_test.go @@ -0,0 +1,26 @@ +package cli_test + +import ( + "github.com/gol4ng/cli" + "github.com/stretchr/testify/assert" + "testing" +) + +func Test_Builder_SGR(t *testing.T) { + tests := []struct { + name string + attributes []cli.Attribute + expected string + }{ + {name: "clean", expected: "test", attributes: []cli.Attribute{}}, + {name: "styles", expected: "\x1b[0;1;2;3;4;5;6;7;8;9mtest", attributes: []cli.Attribute{cli.Reset, cli.Bold, cli.Faint, cli.Italic, cli.Underline, cli.BlinkSlow, cli.BlinkRapid, cli.ReverseVideo, cli.Concealed, cli.CrossedOut}}, + {name: "colors", expected: "\x1b[39;30;31;32;33;34;35;36;37;90;91;92;93;94;95;96;97mtest", attributes: []cli.Attribute{cli.Default, cli.Black, cli.Red, cli.Green, cli.Yellow, cli.Blue, cli.Magenta, cli.Cyan, cli.White, cli.HiBlack, cli.HiRed, cli.HiGreen, cli.HiYellow, cli.HiBlue, cli.HiMagenta, cli.HiCyan, cli.HiWhite}}, + {name: "background colors", expected: "\x1b[49;40;41;42;43;44;45;46;47;100;101;102;103;104;105;106;107mtest", attributes: []cli.Attribute{cli.BgDefault, cli.BgBlack, cli.BgRed, cli.BgGreen, cli.BgYellow, cli.BgBlue, cli.BgMagenta, cli.BgCyan, cli.BgWhite, cli.BgHiBlack, cli.BgHiRed, cli.BgHiGreen, cli.BgHiYellow, cli.BgHiBlue, cli.BgHiMagenta, cli.BgHiCyan, cli.BgHiWhite}}, + } + + for _, test := range tests { + builder := cli.NewStringBuilder() + builder.Style(test.attributes...).WriteString("test") + assert.Equal(t, test.expected, builder.String()) + } +} diff --git a/unicode/block_elements.go b/unicode/block_elements.go new file mode 100644 index 0000000..ce606bb --- /dev/null +++ b/unicode/block_elements.go @@ -0,0 +1,43 @@ +// This was was generated +// DO NOT EDIT THIS FILE +// +// Unicode version: 10.0.0 +// CLDR version: 32 + +package unicode + +const ( + UpperHalfBlock = '▀' // 9600 + LowerOneEighthBlock = '▁' // 9601 + LowerOneQuarterBlock = '▂' // 9602 + LowerThreeEighthsBlock = '▃' // 9603 + LowerHalfBlock = '▄' // 9604 + LowerFiveEighthsBlock = '▅' // 9605 + LowerThreeQuartersBlock = '▆' // 9606 + LowerSevenEighthsBlock = '▇' // 9607 + FullBlock = '█' // 9608 + LeftSevenEighthsBlock = '▉' // 9609 + LeftThreeQuartersBlock = '▊' // 9610 + LeftFiveEighthsBlock = '▋' // 9611 + LeftHalfBlock = '▌' // 9612 + LeftThreeEighthsBlock = '▍' // 9613 + LeftOneQuarterBlock = '▎' // 9614 + LeftOneEighthBlock = '▏' // 9615 + RightHalfBlock = '▐' // 9616 + LightShade = '░' // 9617 + MediumShade = '▒' // 9618 + DarkShade = '▓' // 9619 + UpperOneEighthBlock = '▔' // 9620 + RightOneEighthBlock = '▕' // 9621 + QuadrantLowerLeft = '▖' // 9622 + QuadrantLowerRight = '▗' // 9623 + QuadrantUpperLeft = '▘' // 9624 + QuadrantUpperLeftAndLowerLeftAndLowerRight = '▙' // 9625 + QuadrantUpperLeftAndLowerRight = '▚' // 9626 + QuadrantUpperLeftAndUpperRightAndLowerLeft = '▛' // 9627 + QuadrantUpperLeftAndUpperRightAndLowerRight = '▜' // 9628 + QuadrantUpperRight = '▝' // 9629 + QuadrantUpperRightAndLowerLeft = '▞' // 9630 + QuadrantUpperRightAndLowerLeftAndLowerRight = '▟' // 9631 + +) diff --git a/unicode/box_drawings.go b/unicode/box_drawings.go new file mode 100644 index 0000000..c4a7153 --- /dev/null +++ b/unicode/box_drawings.go @@ -0,0 +1,139 @@ +// This was was generated +// DO NOT EDIT THIS FILE +// +// Unicode version: 10.0.0 +// CLDR version: 32 + +package unicode + +const ( + BoxDrawingsLightHorizontal = '─' // 9472 + BoxDrawingsHeavyHorizontal = '━' // 9473 + BoxDrawingsLightVertical = '│' // 9474 + BoxDrawingsHeavyVertical = '┃' // 9475 + BoxDrawingsLightTripleDashHorizontal = '┄' // 9476 + BoxDrawingsHeavyTripleDashHorizontal = '┅' // 9477 + BoxDrawingsLightTripleDashVertical = '┆' // 9478 + BoxDrawingsHeavyTripleDashVertical = '┇' // 9479 + BoxDrawingsLightQuadrupleDashHorizontal = '┈' // 9480 + BoxDrawingsHeavyQuadrupleDashHorizontal = '┉' // 9481 + BoxDrawingsLightQuadrupleDashVertical = '┊' // 9482 + BoxDrawingsHeavyQuadrupleDashVertical = '┋' // 9483 + BoxDrawingsLightDownAndRight = '┌' // 9484 + BoxDrawingsDownLightAndRightHeavy = '┍' // 9485 + BoxDrawingsDownHeavyAndRightLight = '┎' // 9486 + BoxDrawingsHeavyDownAndRight = '┏' // 9487 + BoxDrawingsLightDownAndLeft = '┐' // 9488 + BoxDrawingsDownLightAndLeftHeavy = '┑' // 9489 + BoxDrawingsDownHeavyAndLeftLight = '┒' // 9490 + BoxDrawingsHeavyDownAndLeft = '┓' // 9491 + BoxDrawingsLightUpAndRight = '└' // 9492 + BoxDrawingsUpLightAndRightHeavy = '┕' // 9493 + BoxDrawingsUpHeavyAndRightLight = '┖' // 9494 + BoxDrawingsHeavyUpAndRight = '┗' // 9495 + BoxDrawingsLightUpAndLeft = '┘' // 9496 + BoxDrawingsUpLightAndLeftHeavy = '┙' // 9497 + BoxDrawingsUpHeavyAndLeftLight = '┚' // 9498 + BoxDrawingsHeavyUpAndLeft = '┛' // 9499 + BoxDrawingsLightVerticalAndRight = '├' // 9500 + BoxDrawingsVerticalLightAndRightHeavy = '┝' // 9501 + BoxDrawingsUpHeavyAndRightDownLight = '┞' // 9502 + BoxDrawingsDownHeavyAndRightUpLight = '┟' // 9503 + BoxDrawingsVerticalHeavyAndRightLight = '┠' // 9504 + BoxDrawingsDownLightAndRightUpHeavy = '┡' // 9505 + BoxDrawingsUpLightAndRightDownHeavy = '┢' // 9506 + BoxDrawingsHeavyVerticalAndRight = '┣' // 9507 + BoxDrawingsLightVerticalAndLeft = '┤' // 9508 + BoxDrawingsVerticalLightAndLeftHeavy = '┥' // 9509 + BoxDrawingsUpHeavyAndLeftDownLight = '┦' // 9510 + BoxDrawingsDownHeavyAndLeftUpLight = '┧' // 9511 + BoxDrawingsVerticalHeavyAndLeftLight = '┨' // 9512 + BoxDrawingsDownLightAndLeftUpHeavy = '┩' // 9513 + BoxDrawingsUpLightAndLeftDownHeavy = '┪' // 9514 + BoxDrawingsHeavyVerticalAndLeft = '┫' // 9515 + BoxDrawingsLightDownAndHorizontal = '┬' // 9516 + BoxDrawingsLeftHeavyAndRightDownLight = '┭' // 9517 + BoxDrawingsRightHeavyAndLeftDownLight = '┮' // 9518 + BoxDrawingsDownLightAndHorizontalHeavy = '┯' // 9519 + BoxDrawingsDownHeavyAndHorizontalLight = '┰' // 9520 + BoxDrawingsRightLightAndLeftDownHeavy = '┱' // 9521 + BoxDrawingsLeftLightAndRightDownHeavy = '┲' // 9522 + BoxDrawingsHeavyDownAndHorizontal = '┳' // 9523 + BoxDrawingsLightUpAndHorizontal = '┴' // 9524 + BoxDrawingsLeftHeavyAndRightUpLight = '┵' // 9525 + BoxDrawingsRightHeavyAndLeftUpLight = '┶' // 9526 + BoxDrawingsUpLightAndHorizontalHeavy = '┷' // 9527 + BoxDrawingsUpHeavyAndHorizontalLight = '┸' // 9528 + BoxDrawingsRightLightAndLeftUpHeavy = '┹' // 9529 + BoxDrawingsLeftLightAndRightUpHeavy = '┺' // 9530 + BoxDrawingsHeavyUpAndHorizontal = '┻' // 9531 + BoxDrawingsLightVerticalAndHorizontal = '┼' // 9532 + BoxDrawingsLeftHeavyAndRightVerticalLight = '┽' // 9533 + BoxDrawingsRightHeavyAndLeftVerticalLight = '┾' // 9534 + BoxDrawingsVerticalLightAndHorizontalHeavy = '┿' // 9535 + BoxDrawingsUpHeavyAndDownHorizontalLight = '╀' // 9536 + BoxDrawingsDownHeavyAndUpHorizontalLight = '╁' // 9537 + BoxDrawingsVerticalHeavyAndHorizontalLight = '╂' // 9538 + BoxDrawingsLeftUpHeavyAndRightDownLight = '╃' // 9539 + BoxDrawingsRightUpHeavyAndLeftDownLight = '╄' // 9540 + BoxDrawingsLeftDownHeavyAndRightUpLight = '╅' // 9541 + BoxDrawingsRightDownHeavyAndLeftUpLight = '╆' // 9542 + BoxDrawingsDownLightAndUpHorizontalHeavy = '╇' // 9543 + BoxDrawingsUpLightAndDownHorizontalHeavy = '╈' // 9544 + BoxDrawingsRightLightAndLeftVerticalHeavy = '╉' // 9545 + BoxDrawingsLeftLightAndRightVerticalHeavy = '╊' // 9546 + BoxDrawingsHeavyVerticalAndHorizontal = '╋' // 9547 + BoxDrawingsLightDoubleDashHorizontal = '╌' // 9548 + BoxDrawingsHeavyDoubleDashHorizontal = '╍' // 9549 + BoxDrawingsLightDoubleDashVertical = '╎' // 9550 + BoxDrawingsHeavyDoubleDashVertical = '╏' // 9551 + BoxDrawingsDoubleHorizontal = '═' // 9552 + BoxDrawingsDoubleVertical = '║' // 9553 + BoxDrawingsDownSingleAndRightDouble = '╒' // 9554 + BoxDrawingsDownDoubleAndRightSingle = '╓' // 9555 + BoxDrawingsDoubleDownAndRight = '╔' // 9556 + BoxDrawingsDownSingleAndLeftDouble = '╕' // 9557 + BoxDrawingsDownDoubleAndLeftSingle = '╖' // 9558 + BoxDrawingsDoubleDownAndLeft = '╗' // 9559 + BoxDrawingsUpSingleAndRightDouble = '╘' // 9560 + BoxDrawingsUpDoubleAndRightSingle = '╙' // 9561 + BoxDrawingsDoubleUpAndRight = '╚' // 9562 + BoxDrawingsUpSingleAndLeftDouble = '╛' // 9563 + BoxDrawingsUpDoubleAndLeftSingle = '╜' // 9564 + BoxDrawingsDoubleUpAndLeft = '╝' // 9565 + BoxDrawingsVerticalSingleAndRightDouble = '╞' // 9566 + BoxDrawingsVerticalDoubleAndRightSingle = '╟' // 9567 + BoxDrawingsDoubleVerticalAndRight = '╠' // 9568 + BoxDrawingsVerticalSingleAndLeftDouble = '╡' // 9569 + BoxDrawingsVerticalDoubleAndLeftSingle = '╢' // 9570 + BoxDrawingsDoubleVerticalAndLeft = '╣' // 9571 + BoxDrawingsDownSingleAndHorizontalDouble = '╤' // 9572 + BoxDrawingsDownDoubleAndHorizontalSingle = '╥' // 9573 + BoxDrawingsDoubleDownAndHorizontal = '╦' // 9574 + BoxDrawingsUpSingleAndHorizontalDouble = '╧' // 9575 + BoxDrawingsUpDoubleAndHorizontalSingle = '╨' // 9576 + BoxDrawingsDoubleUpAndHorizontal = '╩' // 9577 + BoxDrawingsVerticalSingleAndHorizontalDouble = '╪' // 9578 + BoxDrawingsVerticalDoubleAndHorizontalSingle = '╫' // 9579 + BoxDrawingsDoubleVerticalAndHorizontal = '╬' // 9580 + BoxDrawingsLightArcDownAndRight = '╭' // 9581 + BoxDrawingsLightArcDownAndLeft = '╮' // 9582 + BoxDrawingsLightArcUpAndLeft = '╯' // 9583 + BoxDrawingsLightArcUpAndRight = '╰' // 9584 + BoxDrawingsLightDiagonalUpperRightToLowerLeft = '╱' // 9585 + BoxDrawingsLightDiagonalUpperLeftToLowerRight = '╲' // 9586 + BoxDrawingsLightDiagonalCross = '╳' // 9587 + BoxDrawingsLightLeft = '╴' // 9588 + BoxDrawingsLightUp = '╵' // 9589 + BoxDrawingsLightRight = '╶' // 9590 + BoxDrawingsLightDown = '╷' // 9591 + BoxDrawingsHeavyLeft = '╸' // 9592 + BoxDrawingsHeavyUp = '╹' // 9593 + BoxDrawingsHeavyRight = '╺' // 9594 + BoxDrawingsHeavyDown = '╻' // 9595 + BoxDrawingsLightLeftAndHeavyRight = '╼' // 9596 + BoxDrawingsLightUpAndHeavyDown = '╽' // 9597 + BoxDrawingsHeavyLeftAndLightRight = '╾' // 9598 + BoxDrawingsHeavyUpAndLightDown = '╿' // 9599 + +) diff --git a/unicode/braille_pattern.go b/unicode/braille_pattern.go new file mode 100644 index 0000000..4cfd00b --- /dev/null +++ b/unicode/braille_pattern.go @@ -0,0 +1,267 @@ +// This was was generated +// DO NOT EDIT THIS FILE +// +// Unicode version: 10.0.0 +// CLDR version: 32 + +package unicode + +const ( + BraillePatternBlank = '⠀' // 10240 + BraillePatternDots_1 = '⠁' // 10241 + BraillePatternDots_2 = '⠂' // 10242 + BraillePatternDots_12 = '⠃' // 10243 + BraillePatternDots_3 = '⠄' // 10244 + BraillePatternDots_13 = '⠅' // 10245 + BraillePatternDots_23 = '⠆' // 10246 + BraillePatternDots_123 = '⠇' // 10247 + BraillePatternDots_4 = '⠈' // 10248 + BraillePatternDots_14 = '⠉' // 10249 + BraillePatternDots_24 = '⠊' // 10250 + BraillePatternDots_124 = '⠋' // 10251 + BraillePatternDots_34 = '⠌' // 10252 + BraillePatternDots_134 = '⠍' // 10253 + BraillePatternDots_234 = '⠎' // 10254 + BraillePatternDots_1234 = '⠏' // 10255 + BraillePatternDots_5 = '⠐' // 10256 + BraillePatternDots_15 = '⠑' // 10257 + BraillePatternDots_25 = '⠒' // 10258 + BraillePatternDots_125 = '⠓' // 10259 + BraillePatternDots_35 = '⠔' // 10260 + BraillePatternDots_135 = '⠕' // 10261 + BraillePatternDots_235 = '⠖' // 10262 + BraillePatternDots_1235 = '⠗' // 10263 + BraillePatternDots_45 = '⠘' // 10264 + BraillePatternDots_145 = '⠙' // 10265 + BraillePatternDots_245 = '⠚' // 10266 + BraillePatternDots_1245 = '⠛' // 10267 + BraillePatternDots_345 = '⠜' // 10268 + BraillePatternDots_1345 = '⠝' // 10269 + BraillePatternDots_2345 = '⠞' // 10270 + BraillePatternDots_12345 = '⠟' // 10271 + BraillePatternDots_6 = '⠠' // 10272 + BraillePatternDots_16 = '⠡' // 10273 + BraillePatternDots_26 = '⠢' // 10274 + BraillePatternDots_126 = '⠣' // 10275 + BraillePatternDots_36 = '⠤' // 10276 + BraillePatternDots_136 = '⠥' // 10277 + BraillePatternDots_236 = '⠦' // 10278 + BraillePatternDots_1236 = '⠧' // 10279 + BraillePatternDots_46 = '⠨' // 10280 + BraillePatternDots_146 = '⠩' // 10281 + BraillePatternDots_246 = '⠪' // 10282 + BraillePatternDots_1246 = '⠫' // 10283 + BraillePatternDots_346 = '⠬' // 10284 + BraillePatternDots_1346 = '⠭' // 10285 + BraillePatternDots_2346 = '⠮' // 10286 + BraillePatternDots_12346 = '⠯' // 10287 + BraillePatternDots_56 = '⠰' // 10288 + BraillePatternDots_156 = '⠱' // 10289 + BraillePatternDots_256 = '⠲' // 10290 + BraillePatternDots_1256 = '⠳' // 10291 + BraillePatternDots_356 = '⠴' // 10292 + BraillePatternDots_1356 = '⠵' // 10293 + BraillePatternDots_2356 = '⠶' // 10294 + BraillePatternDots_12356 = '⠷' // 10295 + BraillePatternDots_456 = '⠸' // 10296 + BraillePatternDots_1456 = '⠹' // 10297 + BraillePatternDots_2456 = '⠺' // 10298 + BraillePatternDots_12456 = '⠻' // 10299 + BraillePatternDots_3456 = '⠼' // 10300 + BraillePatternDots_13456 = '⠽' // 10301 + BraillePatternDots_23456 = '⠾' // 10302 + BraillePatternDots_123456 = '⠿' // 10303 + BraillePatternDots_7 = '⡀' // 10304 + BraillePatternDots_17 = '⡁' // 10305 + BraillePatternDots_27 = '⡂' // 10306 + BraillePatternDots_127 = '⡃' // 10307 + BraillePatternDots_37 = '⡄' // 10308 + BraillePatternDots_137 = '⡅' // 10309 + BraillePatternDots_237 = '⡆' // 10310 + BraillePatternDots_1237 = '⡇' // 10311 + BraillePatternDots_47 = '⡈' // 10312 + BraillePatternDots_147 = '⡉' // 10313 + BraillePatternDots_247 = '⡊' // 10314 + BraillePatternDots_1247 = '⡋' // 10315 + BraillePatternDots_347 = '⡌' // 10316 + BraillePatternDots_1347 = '⡍' // 10317 + BraillePatternDots_2347 = '⡎' // 10318 + BraillePatternDots_12347 = '⡏' // 10319 + BraillePatternDots_57 = '⡐' // 10320 + BraillePatternDots_157 = '⡑' // 10321 + BraillePatternDots_257 = '⡒' // 10322 + BraillePatternDots_1257 = '⡓' // 10323 + BraillePatternDots_357 = '⡔' // 10324 + BraillePatternDots_1357 = '⡕' // 10325 + BraillePatternDots_2357 = '⡖' // 10326 + BraillePatternDots_12357 = '⡗' // 10327 + BraillePatternDots_457 = '⡘' // 10328 + BraillePatternDots_1457 = '⡙' // 10329 + BraillePatternDots_2457 = '⡚' // 10330 + BraillePatternDots_12457 = '⡛' // 10331 + BraillePatternDots_3457 = '⡜' // 10332 + BraillePatternDots_13457 = '⡝' // 10333 + BraillePatternDots_23457 = '⡞' // 10334 + BraillePatternDots_123457 = '⡟' // 10335 + BraillePatternDots_67 = '⡠' // 10336 + BraillePatternDots_167 = '⡡' // 10337 + BraillePatternDots_267 = '⡢' // 10338 + BraillePatternDots_1267 = '⡣' // 10339 + BraillePatternDots_367 = '⡤' // 10340 + BraillePatternDots_1367 = '⡥' // 10341 + BraillePatternDots_2367 = '⡦' // 10342 + BraillePatternDots_12367 = '⡧' // 10343 + BraillePatternDots_467 = '⡨' // 10344 + BraillePatternDots_1467 = '⡩' // 10345 + BraillePatternDots_2467 = '⡪' // 10346 + BraillePatternDots_12467 = '⡫' // 10347 + BraillePatternDots_3467 = '⡬' // 10348 + BraillePatternDots_13467 = '⡭' // 10349 + BraillePatternDots_23467 = '⡮' // 10350 + BraillePatternDots_123467 = '⡯' // 10351 + BraillePatternDots_567 = '⡰' // 10352 + BraillePatternDots_1567 = '⡱' // 10353 + BraillePatternDots_2567 = '⡲' // 10354 + BraillePatternDots_12567 = '⡳' // 10355 + BraillePatternDots_3567 = '⡴' // 10356 + BraillePatternDots_13567 = '⡵' // 10357 + BraillePatternDots_23567 = '⡶' // 10358 + BraillePatternDots_123567 = '⡷' // 10359 + BraillePatternDots_4567 = '⡸' // 10360 + BraillePatternDots_14567 = '⡹' // 10361 + BraillePatternDots_24567 = '⡺' // 10362 + BraillePatternDots_124567 = '⡻' // 10363 + BraillePatternDots_34567 = '⡼' // 10364 + BraillePatternDots_134567 = '⡽' // 10365 + BraillePatternDots_234567 = '⡾' // 10366 + BraillePatternDots_1234567 = '⡿' // 10367 + BraillePatternDots_8 = '⢀' // 10368 + BraillePatternDots_18 = '⢁' // 10369 + BraillePatternDots_28 = '⢂' // 10370 + BraillePatternDots_128 = '⢃' // 10371 + BraillePatternDots_38 = '⢄' // 10372 + BraillePatternDots_138 = '⢅' // 10373 + BraillePatternDots_238 = '⢆' // 10374 + BraillePatternDots_1238 = '⢇' // 10375 + BraillePatternDots_48 = '⢈' // 10376 + BraillePatternDots_148 = '⢉' // 10377 + BraillePatternDots_248 = '⢊' // 10378 + BraillePatternDots_1248 = '⢋' // 10379 + BraillePatternDots_348 = '⢌' // 10380 + BraillePatternDots_1348 = '⢍' // 10381 + BraillePatternDots_2348 = '⢎' // 10382 + BraillePatternDots_12348 = '⢏' // 10383 + BraillePatternDots_58 = '⢐' // 10384 + BraillePatternDots_158 = '⢑' // 10385 + BraillePatternDots_258 = '⢒' // 10386 + BraillePatternDots_1258 = '⢓' // 10387 + BraillePatternDots_358 = '⢔' // 10388 + BraillePatternDots_1358 = '⢕' // 10389 + BraillePatternDots_2358 = '⢖' // 10390 + BraillePatternDots_12358 = '⢗' // 10391 + BraillePatternDots_458 = '⢘' // 10392 + BraillePatternDots_1458 = '⢙' // 10393 + BraillePatternDots_2458 = '⢚' // 10394 + BraillePatternDots_12458 = '⢛' // 10395 + BraillePatternDots_3458 = '⢜' // 10396 + BraillePatternDots_13458 = '⢝' // 10397 + BraillePatternDots_23458 = '⢞' // 10398 + BraillePatternDots_123458 = '⢟' // 10399 + BraillePatternDots_68 = '⢠' // 10400 + BraillePatternDots_168 = '⢡' // 10401 + BraillePatternDots_268 = '⢢' // 10402 + BraillePatternDots_1268 = '⢣' // 10403 + BraillePatternDots_368 = '⢤' // 10404 + BraillePatternDots_1368 = '⢥' // 10405 + BraillePatternDots_2368 = '⢦' // 10406 + BraillePatternDots_12368 = '⢧' // 10407 + BraillePatternDots_468 = '⢨' // 10408 + BraillePatternDots_1468 = '⢩' // 10409 + BraillePatternDots_2468 = '⢪' // 10410 + BraillePatternDots_12468 = '⢫' // 10411 + BraillePatternDots_3468 = '⢬' // 10412 + BraillePatternDots_13468 = '⢭' // 10413 + BraillePatternDots_23468 = '⢮' // 10414 + BraillePatternDots_123468 = '⢯' // 10415 + BraillePatternDots_568 = '⢰' // 10416 + BraillePatternDots_1568 = '⢱' // 10417 + BraillePatternDots_2568 = '⢲' // 10418 + BraillePatternDots_12568 = '⢳' // 10419 + BraillePatternDots_3568 = '⢴' // 10420 + BraillePatternDots_13568 = '⢵' // 10421 + BraillePatternDots_23568 = '⢶' // 10422 + BraillePatternDots_123568 = '⢷' // 10423 + BraillePatternDots_4568 = '⢸' // 10424 + BraillePatternDots_14568 = '⢹' // 10425 + BraillePatternDots_24568 = '⢺' // 10426 + BraillePatternDots_124568 = '⢻' // 10427 + BraillePatternDots_34568 = '⢼' // 10428 + BraillePatternDots_134568 = '⢽' // 10429 + BraillePatternDots_234568 = '⢾' // 10430 + BraillePatternDots_1234568 = '⢿' // 10431 + BraillePatternDots_78 = '⣀' // 10432 + BraillePatternDots_178 = '⣁' // 10433 + BraillePatternDots_278 = '⣂' // 10434 + BraillePatternDots_1278 = '⣃' // 10435 + BraillePatternDots_378 = '⣄' // 10436 + BraillePatternDots_1378 = '⣅' // 10437 + BraillePatternDots_2378 = '⣆' // 10438 + BraillePatternDots_12378 = '⣇' // 10439 + BraillePatternDots_478 = '⣈' // 10440 + BraillePatternDots_1478 = '⣉' // 10441 + BraillePatternDots_2478 = '⣊' // 10442 + BraillePatternDots_12478 = '⣋' // 10443 + BraillePatternDots_3478 = '⣌' // 10444 + BraillePatternDots_13478 = '⣍' // 10445 + BraillePatternDots_23478 = '⣎' // 10446 + BraillePatternDots_123478 = '⣏' // 10447 + BraillePatternDots_578 = '⣐' // 10448 + BraillePatternDots_1578 = '⣑' // 10449 + BraillePatternDots_2578 = '⣒' // 10450 + BraillePatternDots_12578 = '⣓' // 10451 + BraillePatternDots_3578 = '⣔' // 10452 + BraillePatternDots_13578 = '⣕' // 10453 + BraillePatternDots_23578 = '⣖' // 10454 + BraillePatternDots_123578 = '⣗' // 10455 + BraillePatternDots_4578 = '⣘' // 10456 + BraillePatternDots_14578 = '⣙' // 10457 + BraillePatternDots_24578 = '⣚' // 10458 + BraillePatternDots_124578 = '⣛' // 10459 + BraillePatternDots_34578 = '⣜' // 10460 + BraillePatternDots_134578 = '⣝' // 10461 + BraillePatternDots_234578 = '⣞' // 10462 + BraillePatternDots_1234578 = '⣟' // 10463 + BraillePatternDots_678 = '⣠' // 10464 + BraillePatternDots_1678 = '⣡' // 10465 + BraillePatternDots_2678 = '⣢' // 10466 + BraillePatternDots_12678 = '⣣' // 10467 + BraillePatternDots_3678 = '⣤' // 10468 + BraillePatternDots_13678 = '⣥' // 10469 + BraillePatternDots_23678 = '⣦' // 10470 + BraillePatternDots_123678 = '⣧' // 10471 + BraillePatternDots_4678 = '⣨' // 10472 + BraillePatternDots_14678 = '⣩' // 10473 + BraillePatternDots_24678 = '⣪' // 10474 + BraillePatternDots_124678 = '⣫' // 10475 + BraillePatternDots_34678 = '⣬' // 10476 + BraillePatternDots_134678 = '⣭' // 10477 + BraillePatternDots_234678 = '⣮' // 10478 + BraillePatternDots_1234678 = '⣯' // 10479 + BraillePatternDots_5678 = '⣰' // 10480 + BraillePatternDots_15678 = '⣱' // 10481 + BraillePatternDots_25678 = '⣲' // 10482 + BraillePatternDots_125678 = '⣳' // 10483 + BraillePatternDots_35678 = '⣴' // 10484 + BraillePatternDots_135678 = '⣵' // 10485 + BraillePatternDots_235678 = '⣶' // 10486 + BraillePatternDots_1235678 = '⣷' // 10487 + BraillePatternDots_45678 = '⣸' // 10488 + BraillePatternDots_145678 = '⣹' // 10489 + BraillePatternDots_245678 = '⣺' // 10490 + BraillePatternDots_1245678 = '⣻' // 10491 + BraillePatternDots_345678 = '⣼' // 10492 + BraillePatternDots_1345678 = '⣽' // 10493 + BraillePatternDots_2345678 = '⣾' // 10494 + BraillePatternDots_12345678 = '⣿' // 10495 + +) diff --git a/unicode/geometric-shapes.go b/unicode/geometric-shapes.go new file mode 100644 index 0000000..ff3bdd4 --- /dev/null +++ b/unicode/geometric-shapes.go @@ -0,0 +1,106 @@ +// This was was generated +// DO NOT EDIT THIS FILE +// +// Unicode version: 10.0.0 +// CLDR version: 32 + +package unicode + +const ( + BlackSquare = '■' // 9632 + WhiteSquare = '□' // 9633 + WhiteSquareWithRoundedCorners = '▢' // 9634 + WhiteSquareContainingBlackSmallSquare = '▣' // 9635 + SquareWithHorizontalFill = '▤' // 9636 + SquareWithVerticalFill = '▥' // 9637 + SquareWithOrthogonalCrosshatchFill = '▦' // 9638 + SquareWithUpperLeftToLowerRightFill = '▧' // 9639 + SquareWithUpperRightToLowerLeftFill = '▨' // 9640 + SquareWithDiagonalCrosshatchFill = '▩' // 9641 + BlackSmallSquare = '▪' // 9642 + WhiteSmallSquare = '▫' // 9643 + BlackRectangle = '▬' // 9644 + WhiteRectangle = '▭' // 9645 + BlackVerticalRectangle = '▮' // 9646 + WhiteVerticalRectangle = '▯' // 9647 + BlackParallelogram = '▰' // 9648 + WhiteParallelogram = '▱' // 9649 + BlackUp_pointingTriangle = '▲' // 9650 + WhiteUp_pointingTriangle = '△' // 9651 + BlackUp_pointingSmallTriangle = '▴' // 9652 + WhiteUp_pointingSmallTriangle = '▵' // 9653 + BlackRight_pointingTriangle = '▶' // 9654 + WhiteRight_pointingTriangle = '▷' // 9655 + BlackRight_pointingSmallTriangle = '▸' // 9656 + WhiteRight_pointingSmallTriangle = '▹' // 9657 + BlackRight_pointingPointer = '►' // 9658 + WhiteRight_pointingPointer = '▻' // 9659 + BlackDown_pointingTriangle = '▼' // 9660 + WhiteDown_pointingTriangle = '▽' // 9661 + BlackDown_pointingSmallTriangle = '▾' // 9662 + WhiteDown_pointingSmallTriangle = '▿' // 9663 + BlackLeft_pointingTriangle = '◀' // 9664 + WhiteLeft_pointingTriangle = '◁' // 9665 + BlackLeft_pointingSmallTriangle = '◂' // 9666 + WhiteLeft_pointingSmallTriangle = '◃' // 9667 + BlackLeft_pointingPointer = '◄' // 9668 + WhiteLeft_pointingPointer = '◅' // 9669 + BlackDiamond = '◆' // 9670 + WhiteDiamond = '◇' // 9671 + WhiteDiamondContainingBlackSmallDiamond = '◈' // 9672 + Fisheye = '◉' // 9673 + Lozenge = '◊' // 9674 + WhiteCircle = '○' // 9675 + DottedCircle = '◌' // 9676 + CircleWithVerticalFill = '◍' // 9677 + Bullseye = '◎' // 9678 + BlackCircle = '●' // 9679 + CircleWithLeftHalfBlack = '◐' // 9680 + CircleWithRightHalfBlack = '◑' // 9681 + CircleWithLowerHalfBlack = '◒' // 9682 + CircleWithUpperHalfBlack = '◓' // 9683 + CircleWithUpperRightQuadrantBlack = '◔' // 9684 + CircleWithAllButUpperLeftQuadrantBlack = '◕' // 9685 + LeftHalfBlackCircle = '◖' // 9686 + RightHalfBlackCircle = '◗' // 9687 + InverseBullet = '◘' // 9688 + InverseWhiteCircle = '◙' // 9689 + UpperHalfInverseWhiteCircle = '◚' // 9690 + LowerHalfInverseWhiteCircle = '◛' // 9691 + UpperLeftQuadrantCircularArc = '◜' // 9692 + UpperRightQuadrantCircularArc = '◝' // 9693 + LowerRightQuadrantCircularArc = '◞' // 9694 + LowerLeftQuadrantCircularArc = '◟' // 9695 + UpperHalfCircle = '◠' // 9696 + LowerHalfCircle = '◡' // 9697 + BlackLowerRightTriangle = '◢' // 9698 + BlackLowerLeftTriangle = '◣' // 9699 + BlackUpperLeftTriangle = '◤' // 9700 + BlackUpperRightTriangle = '◥' // 9701 + WhiteBullet = '◦' // 9702 + SquareWithLeftHalfBlack = '◧' // 9703 + SquareWithRightHalfBlack = '◨' // 9704 + SquareWithUpperLeftDiagonalHalfBlack = '◩' // 9705 + SquareWithLowerRightDiagonalHalfBlack = '◪' // 9706 + WhiteSquareWithVerticalBisectingLine = '◫' // 9707 + WhiteUp_pointingTriangleWithDot = '◬' // 9708 + Up_pointingTriangleWithLeftHalfBlack = '◭' // 9709 + Up_pointingTriangleWithRightHalfBlack = '◮' // 9710 + LargeCircle = '◯' // 9711 + WhiteSquareWithUpperLeftQuadrant = '◰' // 9712 + WhiteSquareWithLowerLeftQuadrant = '◱' // 9713 + WhiteSquareWithLowerRightQuadrant = '◲' // 9714 + WhiteSquareWithUpperRightQuadrant = '◳' // 9715 + WhiteCircleWithUpperLeftQuadrant = '◴' // 9716 + WhiteCircleWithLowerLeftQuadrant = '◵' // 9717 + WhiteCircleWithLowerRightQuadrant = '◶' // 9718 + WhiteCircleWithUpperRightQuadrant = '◷' // 9719 + UpperLeftTriangle = '◸' // 9720 + UpperRightTriangle = '◹' // 9721 + LowerLeftTriangle = '◺' // 9722 + WhiteMediumSquare = '◻' // 9723 + BlackMediumSquare = '◼' // 9724 + WhiteMediumSmallSquare = '◽' // 9725 + BlackMediumSmallSquare = '◾' // 9726 + +)