diff options
| author | Paul Buetow <paul@buetow.org> | 2025-02-05 00:30:29 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-02-05 00:30:29 +0200 |
| commit | 07d9f1840494924dd6ca713493dd3d630e9ad721 (patch) | |
| tree | 1abb8c8788fc3224e405428d6ff3f27d1fc1a295 /internal | |
| parent | 35204effbd09bc14e9e2e93b2f99f0f5a0009b23 (diff) | |
initial generic table
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/main.go | 13 | ||||
| -rw-r--r-- | internal/table/render.go | 57 | ||||
| -rw-r--r-- | internal/table/table.go | 84 |
3 files changed, 154 insertions, 0 deletions
diff --git a/internal/main.go b/internal/main.go index 36fc870..561c136 100644 --- a/internal/main.go +++ b/internal/main.go @@ -10,6 +10,7 @@ import ( "time" "codeberg.org/snonux/gos/internal/config" + "codeberg.org/snonux/gos/internal/table" ) func Main(composeEntryDefault bool) { @@ -30,8 +31,20 @@ func Main(composeEntryDefault bool) { geminiSummaryFor := flag.String("geminiSummaryFor", "", "Generate a summary in Gemini Gemtext format, format is coma separated string of months, e.g. 202410,202411") geminiCapsules := flag.String("geminiCapsules", "foo.zone", "Comma sepaeated list Gemini capsules. Used by geminiEnable to detect Gemtext links") gemtexterEnable := flag.Bool("gemtexterEnable", false, "Add special Gemtexter (the static site generator) tags to the Gemini Gemtext summary") + dev := flag.Bool("dev", false, "For internal development purposes only") flag.Parse() + if *dev { + tab := table.New("foo", "bar", "baz", 3). + Add("hans", "wurst", "klo", 3.3). + Add("Klopapier", "Hans", "Wurst", 7) + + if err := tab.Render(); err != nil { + log.Fatal(err) + } + os.Exit(0) + } + secrets, err := config.NewSecrets(secretsConfigPath) if err != nil { log.Fatal(err) diff --git a/internal/table/render.go b/internal/table/render.go new file mode 100644 index 0000000..edac866 --- /dev/null +++ b/internal/table/render.go @@ -0,0 +1,57 @@ +package table + +import ( + "fmt" + "strings" +) + +type render struct { + tab *Table + lineLen int + separator string +} + +func newRender(tab *Table) render { + r := render{ + tab: tab, + lineLen: len(tab.lengths) + 1, + } + + var separator strings.Builder + + for _, len := range tab.lengths { + separator.WriteString("+") + separator.WriteString(strings.Repeat("-", len+2)) + r.lineLen += len + 3 + } + + separator.WriteString("+\n") + r.separator = separator.String() + + return r +} + +func (r render) String() string { + var sb strings.Builder + + sb.WriteString(r.separator) + r.writeRow(&sb, r.tab.headers) + + sb.WriteString(r.separator) + for _, row := range r.tab.rows { + r.writeRow(&sb, row) + } + sb.WriteString(r.separator) + + return sb.String() +} + +func (r render) writeRow(sb *strings.Builder, row []string) { + for i, col := range row { + sb.WriteString(fmt.Sprintf("| %s ", col)) + for j := len(col); j < r.tab.lengths[i]; j++ { + sb.WriteString(" ") + } + } + sb.WriteString("|\n") +} diff --git a/internal/table/table.go b/internal/table/table.go new file mode 100644 index 0000000..040f50d --- /dev/null +++ b/internal/table/table.go @@ -0,0 +1,84 @@ +package table + +import ( + "fmt" + "strconv" +) + +type row []string + +type Table struct { + headers []string + rows []row + lengths []int // Max length of each col + err error +} + +func New(args ...any) *Table { + + t := Table{ + headers: make([]string, 0, len(args)), + lengths: make([]int, 0, len(args)), + } + + for _, arg := range args { + strVal := val(arg) + t.headers = append(t.headers, strVal) + t.lengths = append(t.lengths, len(strVal)) + } + + return &t +} + +func (t *Table) Add(args ...any) *Table { + if len(args) != len(t.headers) { + t.err = fmt.Errorf("Table row (%v) not same length as table headers (%v)", args, t.headers) + } + if t.err != nil { + return t + } + + row := make(row, 0, len(args)) + for i, arg := range args { + strVal := val(arg) + row = append(row, strVal) + if t.lengths[i] < len(row[i]) { + t.lengths[i] = len(row[i]) + } + } + t.rows = append(t.rows, row) + + return t +} + +func (t *Table) Render() error { + if t.err != nil { + return t.err + } + fmt.Print(newRender(t).String()) + return nil +} + +func val(val any) string { + switch v := val.(type) { + case int: + return strconv.Itoa(v) + case float64: + return fmt.Sprintf("%0.2f", v) + case string: + return v + default: + return fmt.Sprintf("%v", v) + } +} + +// func dataRow(sb *strings.Builder, descr1 string, val1 any, descr2 string, val2 any) { +// const format = "| %-21s | %-11s | %-21s | %-11s |" +// sb.WriteString(colour.SInfo2f(format, descr1, val(val1), descr2, val(val2))) +// sb.WriteString("\n") +// } + +// func (t *Table) separator() { +// t.sb.WriteString(t.sep) +// t.sb.WriteString("\n") +// } |
