summaryrefslogtreecommitdiffstats
path: root/pkg/common/draw.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-10-20 23:07:42 +0200
committerDaniel Baumann <daniel@debian.org>2024-11-09 15:38:42 +0100
commit714c83b2736d7e308bc33c49057952490eb98be2 (patch)
tree1d9ba7035798368569cd49056f4d596efc908cd8 /pkg/common/draw.go
parentInitial commit. (diff)
downloadforgejo-act-upstream/1.21.4.tar.xz
forgejo-act-upstream/1.21.4.zip
Adding upstream version 1.21.4.HEADupstream/1.21.4upstreamdebian
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'pkg/common/draw.go')
-rw-r--r--pkg/common/draw.go143
1 files changed, 143 insertions, 0 deletions
diff --git a/pkg/common/draw.go b/pkg/common/draw.go
new file mode 100644
index 0000000..b5b21fe
--- /dev/null
+++ b/pkg/common/draw.go
@@ -0,0 +1,143 @@
+package common
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strings"
+)
+
+// Style is a specific style
+type Style int
+
+// Styles
+const (
+ StyleDoubleLine = iota
+ StyleSingleLine
+ StyleDashedLine
+ StyleNoLine
+)
+
+// NewPen creates a new pen
+func NewPen(style Style, color int) *Pen {
+ bgcolor := 49
+ if os.Getenv("CLICOLOR") == "0" {
+ color = 0
+ bgcolor = 0
+ }
+ return &Pen{
+ style: style,
+ color: color,
+ bgcolor: bgcolor,
+ }
+}
+
+type styleDef struct {
+ cornerTL string
+ cornerTR string
+ cornerBL string
+ cornerBR string
+ lineH string
+ lineV string
+}
+
+var styleDefs = []styleDef{
+ {"\u2554", "\u2557", "\u255a", "\u255d", "\u2550", "\u2551"},
+ {"\u256d", "\u256e", "\u2570", "\u256f", "\u2500", "\u2502"},
+ {"\u250c", "\u2510", "\u2514", "\u2518", "\u254c", "\u254e"},
+ {" ", " ", " ", " ", " ", " "},
+}
+
+// Pen struct
+type Pen struct {
+ style Style
+ color int
+ bgcolor int
+}
+
+// Drawing struct
+type Drawing struct {
+ buf *strings.Builder
+ width int
+}
+
+func (p *Pen) drawTopBars(buf io.Writer, labels ...string) {
+ style := styleDefs[p.style]
+ for _, label := range labels {
+ bar := strings.Repeat(style.lineH, len(label)+2)
+ fmt.Fprintf(buf, " ")
+ fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor)
+ fmt.Fprintf(buf, "%s%s%s", style.cornerTL, bar, style.cornerTR)
+ fmt.Fprintf(buf, "\x1b[%dm", 0)
+ }
+ fmt.Fprintf(buf, "\n")
+}
+func (p *Pen) drawBottomBars(buf io.Writer, labels ...string) {
+ style := styleDefs[p.style]
+ for _, label := range labels {
+ bar := strings.Repeat(style.lineH, len(label)+2)
+ fmt.Fprintf(buf, " ")
+ fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor)
+ fmt.Fprintf(buf, "%s%s%s", style.cornerBL, bar, style.cornerBR)
+ fmt.Fprintf(buf, "\x1b[%dm", 0)
+ }
+ fmt.Fprintf(buf, "\n")
+}
+func (p *Pen) drawLabels(buf io.Writer, labels ...string) {
+ style := styleDefs[p.style]
+ for _, label := range labels {
+ fmt.Fprintf(buf, " ")
+ fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor)
+ fmt.Fprintf(buf, "%s %s %s", style.lineV, label, style.lineV)
+ fmt.Fprintf(buf, "\x1b[%dm", 0)
+ }
+ fmt.Fprintf(buf, "\n")
+}
+
+// DrawArrow between boxes
+func (p *Pen) DrawArrow() *Drawing {
+ drawing := &Drawing{
+ buf: new(strings.Builder),
+ width: 1,
+ }
+ fmt.Fprintf(drawing.buf, "\x1b[%dm", p.color)
+ fmt.Fprintf(drawing.buf, "\u2b07")
+ fmt.Fprintf(drawing.buf, "\x1b[%dm", 0)
+ return drawing
+}
+
+// DrawBoxes to draw boxes
+func (p *Pen) DrawBoxes(labels ...string) *Drawing {
+ width := 0
+ for _, l := range labels {
+ width += len(l) + 2 + 2 + 1
+ }
+ drawing := &Drawing{
+ buf: new(strings.Builder),
+ width: width,
+ }
+ p.drawTopBars(drawing.buf, labels...)
+ p.drawLabels(drawing.buf, labels...)
+ p.drawBottomBars(drawing.buf, labels...)
+
+ return drawing
+}
+
+// Draw to writer
+func (d *Drawing) Draw(writer io.Writer, centerOnWidth int) {
+ padSize := (centerOnWidth - d.GetWidth()) / 2
+ if padSize < 0 {
+ padSize = 0
+ }
+ for _, l := range strings.Split(d.buf.String(), "\n") {
+ if len(l) > 0 {
+ padding := strings.Repeat(" ", padSize)
+ fmt.Fprintf(writer, "%s%s\n", padding, l)
+ }
+ }
+}
+
+// GetWidth of drawing
+func (d *Drawing) GetWidth() int {
+ return d.width
+}