mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-07 04:40:05 -06:00
build(deps): bump github.com/olekukonko/tablewriter from 1.0.9 to 1.1.0
Bumps [github.com/olekukonko/tablewriter](https://github.com/olekukonko/tablewriter) from 1.0.9 to 1.1.0. - [Commits](https://github.com/olekukonko/tablewriter/compare/v1.0.9...v1.1.0) --- updated-dependencies: - dependency-name: github.com/olekukonko/tablewriter dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
d05d5bdc6f
commit
f4eaa8bd5b
55
vendor/github.com/olekukonko/tablewriter/.golangci.yml
generated
vendored
Normal file
55
vendor/github.com/olekukonko/tablewriter/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
# See for configurations: https://golangci-lint.run/usage/configuration/
|
||||
version: 2
|
||||
# See: https://golangci-lint.run/usage/formatters/
|
||||
formatters:
|
||||
default: none
|
||||
enable:
|
||||
- gofmt # https://pkg.go.dev/cmd/gofmt
|
||||
- gofumpt # https://github.com/mvdan/gofumpt
|
||||
|
||||
settings:
|
||||
gofmt:
|
||||
simplify: true # Simplify code: gofmt with `-s` option.
|
||||
|
||||
gofumpt:
|
||||
# Module path which contains the source code being formatted.
|
||||
# Default: ""
|
||||
module-path: github.com/olekukonko/tablewriter # Should match with module in go.mod
|
||||
# Choose whether to use the extra rules.
|
||||
# Default: false
|
||||
extra-rules: true
|
||||
|
||||
# See: https://golangci-lint.run/usage/linters/
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- staticcheck
|
||||
- govet
|
||||
- gocritic
|
||||
# - unused # TODO: There are many unused functions, should I directly remove those ?
|
||||
- ineffassign
|
||||
- unconvert
|
||||
- mirror
|
||||
- usestdlibvars
|
||||
- loggercheck
|
||||
- exptostd
|
||||
- godot
|
||||
- perfsprint
|
||||
|
||||
# See: https://golangci-lint.run/usage/false-positives/
|
||||
exclusion:
|
||||
# paths:
|
||||
# rules:
|
||||
|
||||
settings:
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- "-SA1019" # disabled because it warns about deprecated: kept for compatibility will be removed soon
|
||||
- "-ST1019" # disabled because it warns about deprecated: kept for compatibility will be removed soon
|
||||
- "-ST1021" # disabled because it warns to have comment on exported packages
|
||||
- "-ST1000" # disabled because it warns to have comment on exported functions
|
||||
- "-ST1020" # disabled because it warns to have at least one file in a package should have a package comment
|
||||
|
||||
godot:
|
||||
period: false
|
||||
8
vendor/github.com/olekukonko/tablewriter/README.md
generated
vendored
8
vendor/github.com/olekukonko/tablewriter/README.md
generated
vendored
@@ -28,7 +28,7 @@ go get github.com/olekukonko/tablewriter@v0.0.5
|
||||
#### Latest Version
|
||||
The latest stable version
|
||||
```bash
|
||||
go get github.com/olekukonko/tablewriter@v1.0.9
|
||||
go get github.com/olekukonko/tablewriter@v1.1.0
|
||||
```
|
||||
|
||||
**Warning:** Version `v1.0.0` contains missing functionality and should not be used.
|
||||
@@ -62,7 +62,7 @@ func main() {
|
||||
data := [][]string{
|
||||
{"Package", "Version", "Status"},
|
||||
{"tablewriter", "v0.0.5", "legacy"},
|
||||
{"tablewriter", "v1.0.9", "latest"},
|
||||
{"tablewriter", "v1.1.0", "latest"},
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
@@ -77,7 +77,7 @@ func main() {
|
||||
│ PACKAGE │ VERSION │ STATUS │
|
||||
├─────────────┼─────────┼────────┤
|
||||
│ tablewriter │ v0.0.5 │ legacy │
|
||||
│ tablewriter │ v1.0.9 │ latest │
|
||||
│ tablewriter │ v1.1.0 │ latest │
|
||||
└─────────────┴─────────┴────────┘
|
||||
```
|
||||
|
||||
@@ -1081,6 +1081,8 @@ func (t Time) Format() string {
|
||||
|
||||
- `AutoFormat` changes See [#261](https://github.com/olekukonko/tablewriter/issues/261)
|
||||
|
||||
## What is new
|
||||
- `Counting` changes See [#294](https://github.com/olekukonko/tablewriter/issues/294)
|
||||
|
||||
## Command-Line Tool
|
||||
|
||||
|
||||
7
vendor/github.com/olekukonko/tablewriter/config.go
generated
vendored
7
vendor/github.com/olekukonko/tablewriter/config.go
generated
vendored
@@ -14,6 +14,7 @@ type Config struct {
|
||||
Stream tw.StreamConfig
|
||||
Behavior tw.Behavior
|
||||
Widths tw.CellWidth
|
||||
Counter tw.Counter
|
||||
}
|
||||
|
||||
// ConfigBuilder provides a fluent interface for building Config
|
||||
@@ -199,11 +200,7 @@ func (b *ConfigBuilder) WithHeaderMergeMode(mergeMode int) *ConfigBuilder {
|
||||
// WithMaxWidth sets the maximum width for the entire table (0 means unlimited).
|
||||
// Negative values are treated as 0.
|
||||
func (b *ConfigBuilder) WithMaxWidth(width int) *ConfigBuilder {
|
||||
if width < 0 {
|
||||
b.config.MaxWidth = 0
|
||||
} else {
|
||||
b.config.MaxWidth = width
|
||||
}
|
||||
b.config.MaxWidth = max(width, 0)
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
52
vendor/github.com/olekukonko/tablewriter/option.go
generated
vendored
52
vendor/github.com/olekukonko/tablewriter/option.go
generated
vendored
@@ -1,11 +1,12 @@
|
||||
package tablewriter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Option defines a function type for configuring a Table instance.
|
||||
@@ -498,6 +499,17 @@ func WithTrimSpace(state tw.State) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithTrimLine sets whether empty visual lines within a cell are trimmed.
|
||||
// Logs the change if debugging is enabled.
|
||||
func WithTrimLine(state tw.State) Option {
|
||||
return func(target *Table) {
|
||||
target.config.Behavior.TrimLine = state
|
||||
if target.logger != nil {
|
||||
target.logger.Debugf("Option: WithTrimLine applied to Table: %v", state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithHeaderAutoFormat enables or disables automatic formatting for header cells.
|
||||
// Logs the change if debugging is enabled.
|
||||
func WithHeaderAutoFormat(state tw.State) Option {
|
||||
@@ -607,10 +619,8 @@ func WithRendition(rendition tw.Rendition) Option {
|
||||
if target.logger != nil {
|
||||
target.logger.Debugf("Option: WithRendition: Applied to renderer via Renditioning.SetRendition(): %+v", rendition)
|
||||
}
|
||||
} else {
|
||||
if target.logger != nil {
|
||||
target.logger.Warnf("Option: WithRendition: Current renderer type %T does not implement tw.Renditioning. Rendition may not be applied as expected.", target.renderer)
|
||||
}
|
||||
} else if target.logger != nil {
|
||||
target.logger.Warnf("Option: WithRendition: Current renderer type %T does not implement tw.Renditioning. Rendition may not be applied as expected.", target.renderer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,15 +664,38 @@ func WithSymbols(symbols tw.Symbols) Option {
|
||||
if target.logger != nil {
|
||||
target.logger.Debugf("Option: WithRendition: Applied to renderer via Renditioning.SetRendition(): %+v", cfg)
|
||||
}
|
||||
} else {
|
||||
if target.logger != nil {
|
||||
target.logger.Warnf("Option: WithRendition: Current renderer type %T does not implement tw.Renditioning. Rendition may not be applied as expected.", target.renderer)
|
||||
}
|
||||
} else if target.logger != nil {
|
||||
target.logger.Warnf("Option: WithRendition: Current renderer type %T does not implement tw.Renditioning. Rendition may not be applied as expected.", target.renderer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithCounters enables line counting by wrapping the table's writer.
|
||||
// If a custom counter (that implements tw.Counter) is provided, it will be used.
|
||||
// If the provided counter is nil, a default tw.LineCounter will be used.
|
||||
// The final count can be retrieved via the table.Lines() method after Render() is called.
|
||||
func WithCounters(counters ...tw.Counter) Option {
|
||||
return func(target *Table) {
|
||||
// Iterate through the provided counters and add any non-nil ones.
|
||||
for _, c := range counters {
|
||||
if c != nil {
|
||||
target.counters = append(target.counters, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithLineCounter enables the default line counter.
|
||||
// A new instance of tw.LineCounter is added to the table's list of counters.
|
||||
// The total count can be retrieved via the table.Lines() method after Render() is called.
|
||||
func WithLineCounter() Option {
|
||||
return func(target *Table) {
|
||||
// Important: Create a new instance so tables don't share counters.
|
||||
target.counters = append(target.counters, &tw.LineCounter{})
|
||||
}
|
||||
}
|
||||
|
||||
// defaultConfig returns a default Config with sensible settings for headers, rows, footers, and behavior.
|
||||
func defaultConfig() Config {
|
||||
return Config{
|
||||
@@ -717,6 +750,7 @@ func defaultConfig() Config {
|
||||
Behavior: tw.Behavior{
|
||||
AutoHide: tw.Off,
|
||||
TrimSpace: tw.On,
|
||||
TrimLine: tw.On,
|
||||
Structs: tw.Struct{
|
||||
AutoHeader: tw.Off,
|
||||
Tags: []string{"json", "db"},
|
||||
|
||||
18
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/width.go
generated
vendored
18
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/width.go
generated
vendored
@@ -2,10 +2,11 @@ package twwidth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// condition holds the global runewidth configuration, including East Asian width settings.
|
||||
@@ -35,15 +36,15 @@ var widthCache map[cacheKey]int
|
||||
// including CSI (Control Sequence Introducer) and OSC (Operating System Command) sequences.
|
||||
// The returned regex can be used to strip ANSI codes from strings.
|
||||
func Filter() *regexp.Regexp {
|
||||
var regESC = "\x1b" // ASCII escape character
|
||||
var regBEL = "\x07" // ASCII bell character
|
||||
regESC := "\x1b" // ASCII escape character
|
||||
regBEL := "\x07" // ASCII bell character
|
||||
|
||||
// ANSI string terminator: either ESC+\ or BEL
|
||||
var regST = "(" + regexp.QuoteMeta(regESC+"\\") + "|" + regexp.QuoteMeta(regBEL) + ")"
|
||||
regST := "(" + regexp.QuoteMeta(regESC+"\\") + "|" + regexp.QuoteMeta(regBEL) + ")"
|
||||
// Control Sequence Introducer (CSI): ESC[ followed by parameters and a final byte
|
||||
var regCSI = regexp.QuoteMeta(regESC+"[") + "[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]"
|
||||
regCSI := regexp.QuoteMeta(regESC+"[") + "[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]"
|
||||
// Operating System Command (OSC): ESC] followed by arbitrary content until a terminator
|
||||
var regOSC = regexp.QuoteMeta(regESC+"]") + ".*?" + regST
|
||||
regOSC := regexp.QuoteMeta(regESC+"]") + ".*?" + regST
|
||||
|
||||
// Combine CSI and OSC patterns into a single regex
|
||||
return regexp.MustCompile("(" + regCSI + "|" + regOSC + ")")
|
||||
@@ -257,11 +258,12 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
terminated := false
|
||||
if seqLen >= 2 {
|
||||
introducer := seqBytes[1]
|
||||
if introducer == '[' {
|
||||
switch introducer {
|
||||
case '[':
|
||||
if seqLen >= 3 && r >= 0x40 && r <= 0x7E {
|
||||
terminated = true
|
||||
}
|
||||
} else if introducer == ']' {
|
||||
case ']':
|
||||
if r == '\x07' {
|
||||
terminated = true
|
||||
} else if seqLen > 1 && seqBytes[seqLen-2] == '\x1b' && r == '\\' { // Check for ST: \x1b\
|
||||
|
||||
44
vendor/github.com/olekukonko/tablewriter/renderer/blueprint.go
generated
vendored
44
vendor/github.com/olekukonko/tablewriter/renderer/blueprint.go
generated
vendored
@@ -1,11 +1,12 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
@@ -283,7 +284,7 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
leftPadChar := padding.Left
|
||||
rightPadChar := padding.Right
|
||||
|
||||
//if f.config.Settings.Cushion.Enabled() || f.config.Settings.Cushion.Default() {
|
||||
// if f.config.Settings.Cushion.Enabled() || f.config.Settings.Cushion.Default() {
|
||||
// if leftPadChar == tw.Empty {
|
||||
// leftPadChar = tw.Space
|
||||
// }
|
||||
@@ -297,10 +298,7 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
padRightWidth := twwidth.Width(rightPadChar)
|
||||
|
||||
// Calculate available width for content
|
||||
availableContentWidth := width - padLeftWidth - padRightWidth
|
||||
if availableContentWidth < 0 {
|
||||
availableContentWidth = 0
|
||||
}
|
||||
availableContentWidth := max(width-padLeftWidth-padRightWidth, 0)
|
||||
f.logger.Debugf("Available content width: %d", availableContentWidth)
|
||||
|
||||
// Truncate content if it exceeds available width
|
||||
@@ -311,10 +309,7 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
}
|
||||
|
||||
// Calculate total padding needed
|
||||
totalPaddingWidth := width - runeWidth
|
||||
if totalPaddingWidth < 0 {
|
||||
totalPaddingWidth = 0
|
||||
}
|
||||
totalPaddingWidth := max(width-runeWidth, 0)
|
||||
f.logger.Debugf("Total padding width: %d", totalPaddingWidth)
|
||||
|
||||
var result strings.Builder
|
||||
@@ -435,7 +430,7 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
prevWidth := ctx.Row.Widths.Get(colIndex - 1)
|
||||
prevCellCtx, prevOk := ctx.Row.Current[colIndex-1]
|
||||
prevIsHMergeEnd := prevOk && prevCellCtx.Merge.Horizontal.Present && prevCellCtx.Merge.Horizontal.End
|
||||
if (prevWidth > 0 || prevIsHMergeEnd) && (!ok || !(cellCtx.Merge.Horizontal.Present && !cellCtx.Merge.Horizontal.Start)) {
|
||||
if (prevWidth > 0 || prevIsHMergeEnd) && (!ok || (!cellCtx.Merge.Horizontal.Present || cellCtx.Merge.Horizontal.Start)) {
|
||||
shouldAddSeparator = true
|
||||
}
|
||||
}
|
||||
@@ -454,10 +449,7 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
if ctx.Row.Position == tw.Row {
|
||||
dynamicTotalWidth := 0
|
||||
for k := 0; k < span && colIndex+k < numCols; k++ {
|
||||
normWidth := ctx.NormalizedWidths.Get(colIndex + k)
|
||||
if normWidth < 0 {
|
||||
normWidth = 0
|
||||
}
|
||||
normWidth := max(ctx.NormalizedWidths.Get(colIndex+k), 0)
|
||||
dynamicTotalWidth += normWidth
|
||||
if k > 0 && separatorDisplayWidth > 0 && ctx.NormalizedWidths.Get(colIndex+k) > 0 {
|
||||
dynamicTotalWidth += separatorDisplayWidth
|
||||
@@ -501,21 +493,24 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
// Set cell padding and alignment
|
||||
padding := cellCtx.Padding
|
||||
align := cellCtx.Align
|
||||
if align == tw.AlignNone {
|
||||
if ctx.Row.Position == tw.Header {
|
||||
switch align {
|
||||
case tw.AlignNone:
|
||||
switch ctx.Row.Position {
|
||||
case tw.Header:
|
||||
align = tw.AlignCenter
|
||||
} else if ctx.Row.Position == tw.Footer {
|
||||
case tw.Footer:
|
||||
align = tw.AlignRight
|
||||
} else {
|
||||
default:
|
||||
align = tw.AlignLeft
|
||||
}
|
||||
f.logger.Debugf("renderLine: col %d (data: '%s') using renderer default align '%s' for position %s.", colIndex, cellCtx.Data, align, ctx.Row.Position)
|
||||
} else if align == tw.Skip {
|
||||
if ctx.Row.Position == tw.Header {
|
||||
case tw.Skip:
|
||||
switch ctx.Row.Position {
|
||||
case tw.Header:
|
||||
align = tw.AlignCenter
|
||||
} else if ctx.Row.Position == tw.Footer {
|
||||
case tw.Footer:
|
||||
align = tw.AlignRight
|
||||
} else {
|
||||
default:
|
||||
align = tw.AlignLeft
|
||||
}
|
||||
f.logger.Debugf("renderLine: col %d (data: '%s') cellCtx.Align was Skip/empty, falling back to basic default '%s'.", colIndex, cellCtx.Data, align)
|
||||
@@ -587,7 +582,6 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
func (f *Blueprint) Rendition(config tw.Rendition) {
|
||||
f.config = mergeRendition(f.config, config)
|
||||
f.logger.Debugf("Blueprint.Rendition updated. New config: %+v", f.config)
|
||||
|
||||
}
|
||||
|
||||
// Ensure Blueprint implements tw.Renditioning
|
||||
|
||||
36
vendor/github.com/olekukonko/tablewriter/renderer/colorized.go
generated
vendored
36
vendor/github.com/olekukonko/tablewriter/renderer/colorized.go
generated
vendored
@@ -1,12 +1,13 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/ll/lh"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
@@ -378,22 +379,19 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
|
||||
// Set default padding characters
|
||||
padLeftCharStr := padding.Left
|
||||
if padLeftCharStr == tw.Empty {
|
||||
padLeftCharStr = tw.Space
|
||||
}
|
||||
// if padLeftCharStr == tw.Empty {
|
||||
// padLeftCharStr = tw.Space
|
||||
//}
|
||||
padRightCharStr := padding.Right
|
||||
if padRightCharStr == tw.Empty {
|
||||
padRightCharStr = tw.Space
|
||||
}
|
||||
// if padRightCharStr == tw.Empty {
|
||||
// padRightCharStr = tw.Space
|
||||
//}
|
||||
|
||||
// Calculate padding widths
|
||||
definedPadLeftWidth := twwidth.Width(padLeftCharStr)
|
||||
definedPadRightWidth := twwidth.Width(padRightCharStr)
|
||||
// Calculate available width for content and alignment
|
||||
availableForContentAndAlign := width - definedPadLeftWidth - definedPadRightWidth
|
||||
if availableForContentAndAlign < 0 {
|
||||
availableForContentAndAlign = 0
|
||||
}
|
||||
availableForContentAndAlign := max(width-definedPadLeftWidth-definedPadRightWidth, 0)
|
||||
|
||||
// Truncate content if it exceeds available width
|
||||
if contentVisualWidth > availableForContentAndAlign {
|
||||
@@ -403,10 +401,7 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
}
|
||||
|
||||
// Calculate remaining space for alignment
|
||||
remainingSpaceForAlignment := availableForContentAndAlign - contentVisualWidth
|
||||
if remainingSpaceForAlignment < 0 {
|
||||
remainingSpaceForAlignment = 0
|
||||
}
|
||||
remainingSpaceForAlignment := max(availableForContentAndAlign-contentVisualWidth, 0)
|
||||
|
||||
// Apply alignment padding
|
||||
leftAlignmentPadSpaces := tw.Empty
|
||||
@@ -539,7 +534,7 @@ func (c *Colorized) renderLine(ctx tw.Formatting, line []string, tint Tint) {
|
||||
shouldAddSeparator := false
|
||||
if i > 0 && c.config.Settings.Separators.BetweenColumns.Enabled() {
|
||||
cellCtx, ok := ctx.Row.Current[i]
|
||||
if !ok || !(cellCtx.Merge.Horizontal.Present && !cellCtx.Merge.Horizontal.Start) {
|
||||
if !ok || (!cellCtx.Merge.Horizontal.Present || cellCtx.Merge.Horizontal.Start) {
|
||||
shouldAddSeparator = true
|
||||
}
|
||||
}
|
||||
@@ -574,10 +569,7 @@ func (c *Colorized) renderLine(ctx tw.Formatting, line []string, tint Tint) {
|
||||
dynamicTotalWidth := 0
|
||||
for k := 0; k < span && i+k < numCols; k++ {
|
||||
colToSum := i + k
|
||||
normWidth := ctx.NormalizedWidths.Get(colToSum)
|
||||
if normWidth < 0 {
|
||||
normWidth = 0
|
||||
}
|
||||
normWidth := max(ctx.NormalizedWidths.Get(colToSum), 0)
|
||||
dynamicTotalWidth += normWidth
|
||||
if k > 0 && separatorDisplayWidth > 0 {
|
||||
dynamicTotalWidth += separatorDisplayWidth
|
||||
@@ -633,7 +625,7 @@ func (c *Colorized) renderLine(ctx tw.Formatting, line []string, tint Tint) {
|
||||
}
|
||||
// Override alignment for footer merges or TOTAL pattern
|
||||
if (ctx.Row.Position == tw.Footer && isHMergeStart) || isTotalPattern {
|
||||
if align != tw.AlignRight {
|
||||
if align == tw.AlignNone {
|
||||
c.logger.Debugf("renderLine: Applying AlignRight override for Footer HMerge/TOTAL pattern at col %d. Original/default align was: %s", i, align)
|
||||
align = tw.AlignRight
|
||||
}
|
||||
|
||||
4
vendor/github.com/olekukonko/tablewriter/renderer/fn.go
generated
vendored
4
vendor/github.com/olekukonko/tablewriter/renderer/fn.go
generated
vendored
@@ -2,6 +2,7 @@ package renderer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
@@ -82,7 +83,6 @@ func defaultColorized() ColorizedConfig {
|
||||
|
||||
// defaultOceanRendererConfig returns a base tw.Rendition for the Ocean renderer.
|
||||
func defaultOceanRendererConfig() tw.Rendition {
|
||||
|
||||
return tw.Rendition{
|
||||
Borders: tw.Border{
|
||||
Left: tw.On, Right: tw.On, Top: tw.On, Bottom: tw.On,
|
||||
@@ -190,7 +190,7 @@ func mergeSettings(defaults, overrides tw.Settings) tw.Settings {
|
||||
defaults.CompactMode = overrides.CompactMode
|
||||
}
|
||||
|
||||
//if overrides.Cushion != tw.Unknown {
|
||||
// if overrides.Cushion != tw.Unknown {
|
||||
// defaults.Cushion = overrides.Cushion
|
||||
//}
|
||||
|
||||
|
||||
5
vendor/github.com/olekukonko/tablewriter/renderer/html.go
generated
vendored
5
vendor/github.com/olekukonko/tablewriter/renderer/html.go
generated
vendored
@@ -3,11 +3,12 @@ package renderer
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/olekukonko/ll"
|
||||
"html"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/ll"
|
||||
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
@@ -82,7 +83,7 @@ func (h *HTML) Config() tw.Rendition {
|
||||
}
|
||||
|
||||
// debugLog appends a formatted message to the debug trace if debugging is enabled.
|
||||
//func (h *HTML) debugLog(format string, a ...interface{}) {
|
||||
// func (h *HTML) debugLog(format string, a ...interface{}) {
|
||||
// if h.debug {
|
||||
// msg := fmt.Sprintf(format, a...)
|
||||
// h.trace = append(h.trace, fmt.Sprintf("[HTML] %s", msg))
|
||||
|
||||
34
vendor/github.com/olekukonko/tablewriter/renderer/markdown.go
generated
vendored
34
vendor/github.com/olekukonko/tablewriter/renderer/markdown.go
generated
vendored
@@ -1,11 +1,12 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
@@ -95,7 +96,6 @@ func (m *Markdown) Row(row []string, ctx tw.Formatting) {
|
||||
m.resolveAlignment(ctx)
|
||||
m.logger.Debugf("Rendering row with data=%v, widths=%v, previous=%v, current=%v, next=%v", row, ctx.Row.Widths, ctx.Row.Previous, ctx.Row.Current, ctx.Row.Next)
|
||||
m.renderMarkdownLine(row, ctx, false)
|
||||
|
||||
}
|
||||
|
||||
// Footer renders the Markdown table footer.
|
||||
@@ -155,7 +155,7 @@ func (m *Markdown) resolveAlignment(ctx tw.Formatting) tw.Alignment {
|
||||
|
||||
// formatCell formats a Markdown cell's content with padding and alignment, ensuring at least 3 characters wide.
|
||||
func (m *Markdown) formatCell(content string, width int, align tw.Align, padding tw.Padding) string {
|
||||
//if m.config.Settings.TrimWhitespace.Enabled() {
|
||||
// if m.config.Settings.TrimWhitespace.Enabled() {
|
||||
// content = strings.TrimSpace(content)
|
||||
//}
|
||||
contentVisualWidth := twwidth.Width(content)
|
||||
@@ -177,10 +177,7 @@ func (m *Markdown) formatCell(content string, width int, align tw.Align, padding
|
||||
targetWidth := tw.Max(width, minWidth)
|
||||
|
||||
// Calculate padding
|
||||
totalPaddingNeeded := targetWidth - contentVisualWidth
|
||||
if totalPaddingNeeded < 0 {
|
||||
totalPaddingNeeded = 0
|
||||
}
|
||||
totalPaddingNeeded := max(targetWidth-contentVisualWidth, 0)
|
||||
|
||||
var leftPadStr, rightPadStr string
|
||||
switch align {
|
||||
@@ -220,13 +217,14 @@ func (m *Markdown) formatCell(content string, width int, align tw.Align, padding
|
||||
adjNeeded := targetWidth - finalWidth
|
||||
if adjNeeded > 0 {
|
||||
adjStr := strings.Repeat(tw.Space, adjNeeded)
|
||||
if align == tw.AlignRight {
|
||||
switch align {
|
||||
case tw.AlignRight:
|
||||
result = adjStr + result
|
||||
} else if align == tw.AlignCenter {
|
||||
case tw.AlignCenter:
|
||||
leftAdj := adjNeeded / 2
|
||||
rightAdj := adjNeeded - leftAdj
|
||||
result = strings.Repeat(tw.Space, leftAdj) + result + strings.Repeat(tw.Space, rightAdj)
|
||||
} else {
|
||||
default:
|
||||
result += adjStr
|
||||
}
|
||||
} else {
|
||||
@@ -346,10 +344,7 @@ func (m *Markdown) renderMarkdownLine(line []string, ctx tw.Formatting, isHeader
|
||||
span = cellCtx.Merge.Horizontal.Span
|
||||
totalWidth := 0
|
||||
for k := 0; k < span && colIndex+k < numCols; k++ {
|
||||
colWidth := ctx.NormalizedWidths.Get(colIndex + k)
|
||||
if colWidth < 0 {
|
||||
colWidth = 0
|
||||
}
|
||||
colWidth := max(ctx.NormalizedWidths.Get(colIndex+k), 0)
|
||||
totalWidth += colWidth
|
||||
if k > 0 && separatorWidth > 0 {
|
||||
totalWidth += separatorWidth
|
||||
@@ -388,17 +383,18 @@ func (m *Markdown) renderMarkdownLine(line []string, ctx tw.Formatting, isHeader
|
||||
}
|
||||
// For rows, use the header's alignment if specified
|
||||
rowAlign := align
|
||||
if headerCellCtx, headerOK := ctx.Row.Previous[colIndex]; headerOK && isHeaderSep == false {
|
||||
if headerCellCtx, headerOK := ctx.Row.Previous[colIndex]; headerOK && !isHeaderSep {
|
||||
if headerCellCtx.Align != tw.AlignNone && headerCellCtx.Align != tw.Empty {
|
||||
rowAlign = headerCellCtx.Align
|
||||
}
|
||||
}
|
||||
if rowAlign == tw.AlignNone || rowAlign == tw.Empty {
|
||||
if ctx.Row.Position == tw.Header {
|
||||
switch ctx.Row.Position {
|
||||
case tw.Header:
|
||||
rowAlign = tw.AlignCenter
|
||||
} else if ctx.Row.Position == tw.Footer {
|
||||
case tw.Footer:
|
||||
rowAlign = tw.AlignRight
|
||||
} else {
|
||||
default:
|
||||
rowAlign = tw.AlignLeft
|
||||
}
|
||||
m.logger.Debugf("renderMarkdownLine: Col %d using default align '%s'", colIndex, rowAlign)
|
||||
|
||||
26
vendor/github.com/olekukonko/tablewriter/renderer/ocean.go
generated
vendored
26
vendor/github.com/olekukonko/tablewriter/renderer/ocean.go
generated
vendored
@@ -1,17 +1,18 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
// OceanConfig defines configuration specific to the Ocean renderer.
|
||||
type OceanConfig struct {
|
||||
}
|
||||
type OceanConfig struct{}
|
||||
|
||||
// Ocean is a streaming table renderer that writes ASCII tables.
|
||||
type Ocean struct {
|
||||
@@ -327,12 +328,9 @@ func (o *Ocean) renderContentLine(ctx tw.Formatting, lineData []string) {
|
||||
idxInMergeSpan := colIdx + k
|
||||
// Check if idxInMergeSpan is a defined column in fixedWidths
|
||||
foundInFixedWidths := false
|
||||
for _, sortedCIdx_inner := range sortedColIndices {
|
||||
if sortedCIdx_inner == idxInMergeSpan {
|
||||
currentMergeTotalRenderWidth += o.fixedWidths.Get(idxInMergeSpan)
|
||||
foundInFixedWidths = true
|
||||
break
|
||||
}
|
||||
if slices.Contains(sortedColIndices, idxInMergeSpan) {
|
||||
currentMergeTotalRenderWidth += o.fixedWidths.Get(idxInMergeSpan)
|
||||
foundInFixedWidths = true
|
||||
}
|
||||
if !foundInFixedWidths && idxInMergeSpan <= sortedColIndices[len(sortedColIndices)-1] {
|
||||
o.logger.Debugf("Col %d in HMerge span not found in fixedWidths, assuming 0-width contribution.", idxInMergeSpan)
|
||||
@@ -407,20 +405,14 @@ func (o *Ocean) formatCellContent(content string, cellVisualWidth int, padding t
|
||||
padLeftDisplayWidth := twwidth.Width(padLeftChar)
|
||||
padRightDisplayWidth := twwidth.Width(padRightChar)
|
||||
|
||||
spaceForContentAndAlignment := cellVisualWidth - padLeftDisplayWidth - padRightDisplayWidth
|
||||
if spaceForContentAndAlignment < 0 {
|
||||
spaceForContentAndAlignment = 0
|
||||
}
|
||||
spaceForContentAndAlignment := max(cellVisualWidth-padLeftDisplayWidth-padRightDisplayWidth, 0)
|
||||
|
||||
if contentDisplayWidth > spaceForContentAndAlignment {
|
||||
content = twwidth.Truncate(content, spaceForContentAndAlignment)
|
||||
contentDisplayWidth = twwidth.Width(content)
|
||||
}
|
||||
|
||||
remainingSpace := spaceForContentAndAlignment - contentDisplayWidth
|
||||
if remainingSpace < 0 {
|
||||
remainingSpace = 0
|
||||
}
|
||||
remainingSpace := max(spaceForContentAndAlignment-contentDisplayWidth, 0)
|
||||
|
||||
var PL, PR string
|
||||
switch align {
|
||||
|
||||
15
vendor/github.com/olekukonko/tablewriter/renderer/svg.go
generated
vendored
15
vendor/github.com/olekukonko/tablewriter/renderer/svg.go
generated
vendored
@@ -2,11 +2,12 @@ package renderer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/olekukonko/ll"
|
||||
"html"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/ll"
|
||||
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
@@ -512,10 +513,7 @@ func (s *SVG) renderVisualLine(visualLineData []string, ctx tw.Formatting, posit
|
||||
}
|
||||
s.dataRowCounter++
|
||||
} else {
|
||||
parentDataRowStripeIndex := s.dataRowCounter - 1
|
||||
if parentDataRowStripeIndex < 0 {
|
||||
parentDataRowStripeIndex = 0
|
||||
}
|
||||
parentDataRowStripeIndex := max(s.dataRowCounter-1, 0)
|
||||
if s.config.RowAltBG != tw.Empty && parentDataRowStripeIndex%2 != 0 {
|
||||
bgColor = s.config.RowAltBG
|
||||
} else {
|
||||
@@ -623,9 +621,10 @@ func (s *SVG) renderVisualLine(visualLineData []string, ctx tw.Formatting, posit
|
||||
}
|
||||
}
|
||||
textX := currentX + s.config.Padding
|
||||
if cellTextAnchor == "middle" {
|
||||
switch cellTextAnchor {
|
||||
case "middle":
|
||||
textX = currentX + s.config.Padding + (rectWidth-2*s.config.Padding)/2.0
|
||||
} else if cellTextAnchor == "end" {
|
||||
case "end":
|
||||
textX = currentX + rectWidth - s.config.Padding
|
||||
}
|
||||
textY := s.currentY + rectHeight/2.0
|
||||
@@ -686,7 +685,7 @@ func (s *SVG) Start(w io.Writer) error {
|
||||
func (s *SVG) debug(format string, a ...interface{}) {
|
||||
if s.config.Debug {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
s.trace = append(s.trace, fmt.Sprintf("[SVG] %s", msg))
|
||||
s.trace = append(s.trace, "[SVG] "+msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
vendor/github.com/olekukonko/tablewriter/stream.go
generated
vendored
21
vendor/github.com/olekukonko/tablewriter/stream.go
generated
vendored
@@ -1,10 +1,11 @@
|
||||
package tablewriter
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/olekukonko/errors"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Close finalizes the table stream.
|
||||
@@ -92,8 +93,8 @@ func (t *Table) Start() error {
|
||||
return errors.Newf("renderer does not support streaming")
|
||||
}
|
||||
|
||||
//t.renderer.Start(t.writer)
|
||||
//t.renderer.Logger(t.logger)
|
||||
// t.renderer.Start(t.writer)
|
||||
// t.renderer.Logger(t.logger)
|
||||
|
||||
if t.hasPrinted {
|
||||
// Prevent calling Start() multiple times on the same stream instance.
|
||||
@@ -119,7 +120,7 @@ func (t *Table) Start() error {
|
||||
t.streamWidths = t.config.Widths.PerColumn.Clone()
|
||||
// Determine numCols from the highest index in PerColumn map
|
||||
maxColIdx := -1
|
||||
t.streamWidths.Each(func(col int, width int) {
|
||||
t.streamWidths.Each(func(col, width int) {
|
||||
if col > maxColIdx {
|
||||
maxColIdx = col
|
||||
}
|
||||
@@ -331,7 +332,7 @@ func (t *Table) streamAppendRow(row interface{}) error {
|
||||
t.logger.Debug("streamAppendRow: Separator line rendered. Updated lastRenderedPosition to 'separator'.")
|
||||
} else {
|
||||
details := ""
|
||||
if !(shouldDrawHeaderRowSeparator || shouldDrawRowRowSeparator) {
|
||||
if !shouldDrawHeaderRowSeparator && !shouldDrawRowRowSeparator {
|
||||
details = "neither header/row nor row/row separator was flagged true"
|
||||
} else if t.lastRenderedPosition == tw.Position("separator") {
|
||||
details = "lastRenderedPosition is already 'separator'"
|
||||
@@ -475,7 +476,7 @@ func (t *Table) streamCalculateWidths(sampling []string, config tw.CellConfig) i
|
||||
determinedNumCols := 0
|
||||
if t.config.Widths.PerColumn != nil && t.config.Widths.PerColumn.Len() > 0 {
|
||||
maxColIdx := -1
|
||||
t.config.Widths.PerColumn.Each(func(col int, width int) {
|
||||
t.config.Widths.PerColumn.Each(func(col, width int) {
|
||||
if col > maxColIdx {
|
||||
maxColIdx = col
|
||||
}
|
||||
@@ -600,7 +601,7 @@ func (t *Table) streamCalculateWidths(sampling []string, config tw.CellConfig) i
|
||||
if t.config.Widths.Global > 0 && t.streamNumCols > 0 {
|
||||
t.logger.Debug("streamCalculateWidths: Applying global stream width constraint %d", t.config.Widths.Global)
|
||||
currentTotalColumnWidthsSum := 0
|
||||
t.streamWidths.Each(func(_ int, w int) {
|
||||
t.streamWidths.Each(func(_, w int) {
|
||||
currentTotalColumnWidthsSum += w
|
||||
})
|
||||
|
||||
@@ -665,7 +666,7 @@ func (t *Table) streamCalculateWidths(sampling []string, config tw.CellConfig) i
|
||||
// Distribute remainingSpace (positive or negative) among non-zero width columns
|
||||
if remainingSpace != 0 && t.streamNumCols > 0 {
|
||||
colsToAdjust := []int{}
|
||||
t.streamWidths.Each(func(col int, w int) {
|
||||
t.streamWidths.Each(func(col, w int) {
|
||||
if w > 0 { // Only consider columns that currently have width
|
||||
colsToAdjust = append(colsToAdjust, col)
|
||||
}
|
||||
@@ -689,7 +690,7 @@ func (t *Table) streamCalculateWidths(sampling []string, config tw.CellConfig) i
|
||||
}
|
||||
|
||||
// Final sanitization
|
||||
t.streamWidths.Each(func(col int, width int) {
|
||||
t.streamWidths.Each(func(col, width int) {
|
||||
if width < 0 {
|
||||
t.streamWidths.Set(col, 0)
|
||||
}
|
||||
@@ -858,7 +859,7 @@ func (t *Table) streamRenderFooter(processedFooterLines [][]string) error {
|
||||
// If this is the last line of the last content block (footer), and no bottom border will be drawn,
|
||||
// its Location should be End.
|
||||
isLastLineOfTableContent := (i == totalFooterLines-1) &&
|
||||
!(cfg.Borders.Bottom.Enabled() && cfg.Settings.Lines.ShowBottom.Enabled())
|
||||
(!cfg.Borders.Bottom.Enabled() || !cfg.Settings.Lines.ShowBottom.Enabled())
|
||||
if isLastLineOfTableContent {
|
||||
resp.location = tw.LocationEnd
|
||||
t.logger.Debug("streamRenderFooter: Setting LocationEnd for last footer line as no bottom border will follow.")
|
||||
|
||||
136
vendor/github.com/olekukonko/tablewriter/tablewriter.go
generated
vendored
136
vendor/github.com/olekukonko/tablewriter/tablewriter.go
generated
vendored
@@ -2,13 +2,6 @@ package tablewriter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/olekukonko/errors"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/ll/lh"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwarp"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"github.com/olekukonko/tablewriter/renderer"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
@@ -16,11 +9,20 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/olekukonko/errors"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/ll/lh"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwarp"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"github.com/olekukonko/tablewriter/renderer"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
// Table represents a table instance with content and rendering capabilities.
|
||||
type Table struct {
|
||||
writer io.Writer // Destination for table output
|
||||
counters []tw.Counter // Counters for indices
|
||||
rows [][][]string // Row data, supporting multi-line cells
|
||||
headers [][]string // Header content
|
||||
footers [][]string // Footer content
|
||||
@@ -410,7 +412,6 @@ func (t *Table) Footer(elements ...any) {
|
||||
// Parameter opts is a function that modifies the Table struct.
|
||||
// Returns the Table instance for method chaining.
|
||||
func (t *Table) Options(opts ...Option) *Table {
|
||||
|
||||
// add logger
|
||||
if t.logger == nil {
|
||||
t.logger = ll.New("table").Handler(lh.NewTextHandler(t.trace))
|
||||
@@ -423,7 +424,7 @@ func (t *Table) Options(opts ...Option) *Table {
|
||||
|
||||
// force debugging mode if set
|
||||
// This should be move away form WithDebug
|
||||
if t.config.Debug == true {
|
||||
if t.config.Debug {
|
||||
t.logger.Enable()
|
||||
t.logger.Resume()
|
||||
} else {
|
||||
@@ -510,6 +511,28 @@ func (t *Table) Render() error {
|
||||
return t.render()
|
||||
}
|
||||
|
||||
// Lines returns the total number of lines rendered.
|
||||
// This method is only effective if the WithLineCounter() option was used during
|
||||
// table initialization and must be called *after* Render().
|
||||
// It actively searches for the default tw.LineCounter among all active counters.
|
||||
// It returns -1 if the line counter was not enabled.
|
||||
func (t *Table) Lines() int {
|
||||
for _, counter := range t.counters {
|
||||
if lc, ok := counter.(*tw.LineCounter); ok {
|
||||
return lc.Total()
|
||||
}
|
||||
}
|
||||
// use -1 to indicate no line counter is attached
|
||||
return -1
|
||||
}
|
||||
|
||||
// Counters returns the slice of all active counter instances.
|
||||
// This is useful when multiple counters are enabled.
|
||||
// It must be called *after* Render().
|
||||
func (t *Table) Counters() []tw.Counter {
|
||||
return t.counters
|
||||
}
|
||||
|
||||
// Trimmer trims whitespace from a string based on the Table’s configuration.
|
||||
// It conditionally applies strings.TrimSpace to the input string if the TrimSpace behavior
|
||||
// is enabled in t.config.Behavior, otherwise returning the string unchanged. This method
|
||||
@@ -945,10 +968,7 @@ func (t *Table) prepareContent(cells []string, config tw.CellConfig) [][]string
|
||||
currentLine := line
|
||||
breakCharWidth := twwidth.Width(tw.CharBreak)
|
||||
for twwidth.Width(currentLine) > effectiveContentMaxWidth {
|
||||
targetWidth := effectiveContentMaxWidth - breakCharWidth
|
||||
if targetWidth < 0 {
|
||||
targetWidth = 0
|
||||
}
|
||||
targetWidth := max(effectiveContentMaxWidth-breakCharWidth, 0)
|
||||
breakPoint := tw.BreakPoint(currentLine, targetWidth)
|
||||
runes := []rune(currentLine)
|
||||
if breakPoint <= 0 || breakPoint > len(runes) {
|
||||
@@ -1362,23 +1382,40 @@ func (t *Table) prepareWithMerges(content [][]string, config tw.CellConfig, posi
|
||||
// No parameters are required.
|
||||
// Returns an error if rendering fails in any section.
|
||||
func (t *Table) render() error {
|
||||
|
||||
t.ensureInitialized()
|
||||
|
||||
// Save the original writer and schedule its restoration upon function exit.
|
||||
// This guarantees the table's writer is restored even if errors occur.
|
||||
originalWriter := t.writer
|
||||
defer func() {
|
||||
t.writer = originalWriter
|
||||
}()
|
||||
|
||||
// If a counter is active, wrap the writer in a MultiWriter.
|
||||
if len(t.counters) > 0 {
|
||||
// The slice must be of type io.Writer.
|
||||
// Start it with the original destination writer.
|
||||
allWriters := []io.Writer{originalWriter}
|
||||
|
||||
// Append each counter to the slice of writers.
|
||||
for _, c := range t.counters {
|
||||
allWriters = append(allWriters, c)
|
||||
}
|
||||
|
||||
// Create a MultiWriter that broadcasts to the original writer AND all counters.
|
||||
t.writer = io.MultiWriter(allWriters...)
|
||||
}
|
||||
|
||||
if t.config.Stream.Enable {
|
||||
t.logger.Warn("Render() called in streaming mode. Use Start/Append/Close methods instead.")
|
||||
return errors.New("render called in streaming mode; use Start/Append/Close")
|
||||
}
|
||||
|
||||
// Calculate and cache numCols for THIS batch render pass
|
||||
t.batchRenderNumCols = t.maxColumns() // Calculate ONCE
|
||||
t.isBatchRenderNumColsSet = true // Mark the cache as active for this render pass
|
||||
t.logger.Debugf("Render(): Set batchRenderNumCols to %d and isBatchRenderNumColsSet to true.", t.batchRenderNumCols)
|
||||
|
||||
// Calculate and cache the column count for this specific batch render pass.
|
||||
t.batchRenderNumCols = t.maxColumns()
|
||||
t.isBatchRenderNumColsSet = true
|
||||
defer func() {
|
||||
t.isBatchRenderNumColsSet = false
|
||||
// t.batchRenderNumCols = 0; // Optional: reset to 0, or leave as is.
|
||||
// Since isBatchRenderNumColsSet is false, its value won't be used by getNumColsToUse.
|
||||
t.logger.Debugf("Render(): Cleared isBatchRenderNumColsSet to false (batchRenderNumCols was %d).", t.batchRenderNumCols)
|
||||
}()
|
||||
|
||||
@@ -1387,9 +1424,10 @@ func (t *Table) render() error {
|
||||
(t.caption.Spot >= tw.SpotTopLeft && t.caption.Spot <= tw.SpotBottomRight)
|
||||
|
||||
var tableStringBuffer *strings.Builder
|
||||
targetWriter := t.writer
|
||||
originalWriter := t.writer // Save original writer for restoration if needed
|
||||
targetWriter := t.writer // Can be the original writer or the MultiWriter.
|
||||
|
||||
// If a caption is present, the main table content must be rendered to an
|
||||
// in-memory buffer first to calculate its final width.
|
||||
if isTopOrBottomCaption {
|
||||
tableStringBuffer = &strings.Builder{}
|
||||
targetWriter = tableStringBuffer
|
||||
@@ -1398,17 +1436,15 @@ func (t *Table) render() error {
|
||||
t.logger.Debugf("No caption detected. Rendering table core directly to writer.")
|
||||
}
|
||||
|
||||
//Render Table Core
|
||||
// Point the table's writer to the target (either the final destination or the buffer).
|
||||
t.writer = targetWriter
|
||||
ctx, mctx, err := t.prepareContexts()
|
||||
if err != nil {
|
||||
t.writer = originalWriter
|
||||
t.logger.Errorf("prepareContexts failed: %v", err)
|
||||
return errors.Newf("failed to prepare table contexts").Wrap(err)
|
||||
}
|
||||
|
||||
if err := ctx.renderer.Start(t.writer); err != nil {
|
||||
t.writer = originalWriter
|
||||
t.logger.Errorf("Renderer Start() error: %v", err)
|
||||
return errors.Newf("renderer start failed").Wrap(err)
|
||||
}
|
||||
@@ -1440,18 +1476,21 @@ func (t *Table) render() error {
|
||||
renderError = true
|
||||
}
|
||||
|
||||
t.writer = originalWriter // Restore original writer
|
||||
// Restore the writer to the original for the caption-handling logic.
|
||||
// This is necessary because the caption must be written to the final
|
||||
// destination, not the temporary buffer used for the table body.
|
||||
t.writer = originalWriter
|
||||
|
||||
if renderError {
|
||||
return firstRenderErr // Return error from core rendering if any
|
||||
return firstRenderErr
|
||||
}
|
||||
|
||||
//Caption Handling & Final Output ---
|
||||
// Caption Handling & Final Output
|
||||
if isTopOrBottomCaption {
|
||||
renderedTableContent := tableStringBuffer.String()
|
||||
t.logger.Debugf("[Render] Table core buffer length: %d", len(renderedTableContent))
|
||||
|
||||
// Check if the buffer is empty AND borders are enabled
|
||||
// Handle edge case where table is empty but should have borders.
|
||||
shouldHaveBorders := t.renderer != nil && (t.renderer.Config().Borders.Top.Enabled() || t.renderer.Config().Borders.Bottom.Enabled())
|
||||
if len(renderedTableContent) == 0 && shouldHaveBorders {
|
||||
var sb strings.Builder
|
||||
@@ -1503,7 +1542,7 @@ func (t *Table) render() error {
|
||||
|
||||
t.hasPrinted = true
|
||||
t.logger.Info("Render() completed.")
|
||||
return nil // Success
|
||||
return nil
|
||||
}
|
||||
|
||||
// renderFooter renders the table's footer section with borders and padding.
|
||||
@@ -1677,7 +1716,7 @@ func (t *Table) renderFooter(ctx *renderContext, mctx *mergeContext) error {
|
||||
if hasTopPadding {
|
||||
hctx.rowIdx = 0
|
||||
hctx.lineIdx = -1
|
||||
if !(hasContentAbove && cfg.Settings.Lines.ShowFooterLine.Enabled()) {
|
||||
if !hasContentAbove || !cfg.Settings.Lines.ShowFooterLine.Enabled() {
|
||||
hctx.location = tw.LocationFirst
|
||||
} else {
|
||||
hctx.location = tw.LocationMiddle
|
||||
@@ -1699,7 +1738,7 @@ func (t *Table) renderFooter(ctx *renderContext, mctx *mergeContext) error {
|
||||
hctx.line = padLine(line, ctx.numCols)
|
||||
isFirstContentLine := i == 0
|
||||
isLastContentLine := i == len(ctx.footerLines)-1
|
||||
if isFirstContentLine && !hasTopPadding && !(hasContentAbove && cfg.Settings.Lines.ShowFooterLine.Enabled()) {
|
||||
if isFirstContentLine && !hasTopPadding && (!hasContentAbove || !cfg.Settings.Lines.ShowFooterLine.Enabled()) {
|
||||
hctx.location = tw.LocationFirst
|
||||
} else if isLastContentLine && !hasBottomPaddingConfig {
|
||||
hctx.location = tw.LocationEnd
|
||||
@@ -1716,7 +1755,7 @@ func (t *Table) renderFooter(ctx *renderContext, mctx *mergeContext) error {
|
||||
if hasBottomPaddingConfig {
|
||||
paddingLineContentForContext = make([]string, ctx.numCols)
|
||||
formattedPaddingCells := make([]string, ctx.numCols)
|
||||
var representativePadChar string = " "
|
||||
representativePadChar := " "
|
||||
ctx.logger.Debugf("Constructing Footer Bottom Padding line content strings")
|
||||
for j := 0; j < ctx.numCols; j++ {
|
||||
colWd := ctx.widths[tw.Footer].Get(j)
|
||||
@@ -1741,10 +1780,7 @@ func (t *Table) renderFooter(ctx *renderContext, mctx *mergeContext) error {
|
||||
if j == 0 || representativePadChar == " " {
|
||||
representativePadChar = padChar
|
||||
}
|
||||
padWidth := twwidth.Width(padChar)
|
||||
if padWidth < 1 {
|
||||
padWidth = 1
|
||||
}
|
||||
padWidth := max(twwidth.Width(padChar), 1)
|
||||
repeatCount := 0
|
||||
if colWd > 0 && padWidth > 0 {
|
||||
repeatCount = colWd / padWidth
|
||||
@@ -2139,19 +2175,21 @@ func (t *Table) renderRow(ctx *renderContext, mctx *mergeContext) error {
|
||||
hctx.lineIdx = j
|
||||
hctx.line = padLine(visualLineData, ctx.numCols)
|
||||
|
||||
if j > 0 {
|
||||
visualLineHasActualContent := false
|
||||
for kCellIdx, cellContentInVisualLine := range hctx.line {
|
||||
if t.Trimmer(cellContentInVisualLine) != "" {
|
||||
visualLineHasActualContent = true
|
||||
ctx.logger.Debug("Visual line [%d][%d] has content in cell %d: '%s'. Not skipping.", i, j, kCellIdx, cellContentInVisualLine)
|
||||
break
|
||||
if t.config.Behavior.TrimLine.Enabled() {
|
||||
if j > 0 {
|
||||
visualLineHasActualContent := false
|
||||
for kCellIdx, cellContentInVisualLine := range hctx.line {
|
||||
if t.Trimmer(cellContentInVisualLine) != "" {
|
||||
visualLineHasActualContent = true
|
||||
ctx.logger.Debug("Visual line [%d][%d] has content in cell %d: '%s'. Not skipping.", i, j, kCellIdx, cellContentInVisualLine)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !visualLineHasActualContent {
|
||||
ctx.logger.Debug("Skipping visual line [%d][%d] as it's entirely blank after trimming. Line: %q", i, j, hctx.line)
|
||||
continue
|
||||
if !visualLineHasActualContent {
|
||||
ctx.logger.Debug("Skipping visual line [%d][%d] as it's entirely blank after trimming. Line: %q", i, j, hctx.line)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
vendor/github.com/olekukonko/tablewriter/tw/cell.go
generated
vendored
1
vendor/github.com/olekukonko/tablewriter/tw/cell.go
generated
vendored
@@ -12,7 +12,6 @@ type CellFormatting struct {
|
||||
// Deprecated: kept for compatibility
|
||||
// will be removed soon
|
||||
Alignment Align // Text alignment within the cell (e.g., Left, Right, Center)
|
||||
|
||||
}
|
||||
|
||||
// CellPadding defines padding settings for table cells.
|
||||
|
||||
18
vendor/github.com/olekukonko/tablewriter/tw/fn.go
generated
vendored
18
vendor/github.com/olekukonko/tablewriter/tw/fn.go
generated
vendored
@@ -3,12 +3,18 @@
|
||||
package tw
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"math" // For mathematical operations like ceiling
|
||||
"strconv" // For string-to-number conversions
|
||||
"strings" // For string manipulation utilities
|
||||
"unicode" // For Unicode character classification
|
||||
"unicode/utf8" // For UTF-8 rune handling
|
||||
// For mathematical operations like ceiling
|
||||
// For string-to-number conversions
|
||||
// For string manipulation utilities
|
||||
// For Unicode character classification
|
||||
// For UTF-8 rune handling
|
||||
)
|
||||
|
||||
// Title normalizes and uppercases a label string for use in headers.
|
||||
@@ -75,7 +81,7 @@ func PadLeft(s, pad string, width int) string {
|
||||
|
||||
// Pad aligns a string within a specified width using a padding character.
|
||||
// It truncates if the string is wider than the target width.
|
||||
func Pad(s string, padChar string, totalWidth int, alignment Align) string {
|
||||
func Pad(s, padChar string, totalWidth int, alignment Align) string {
|
||||
sDisplayWidth := twwidth.Width(s)
|
||||
if sDisplayWidth > totalWidth {
|
||||
return twwidth.Truncate(s, totalWidth) // Only truncate if necessary
|
||||
|
||||
26
vendor/github.com/olekukonko/tablewriter/tw/mapper.go
generated
vendored
26
vendor/github.com/olekukonko/tablewriter/tw/mapper.go
generated
vendored
@@ -114,21 +114,17 @@ func (m Mapper[K, V]) Values() []V {
|
||||
// Each iterates over each key-value pair in the map and calls the provided function.
|
||||
// Does nothing if the map is nil.
|
||||
func (m Mapper[K, V]) Each(fn func(K, V)) {
|
||||
if m != nil {
|
||||
for k, v := range m {
|
||||
fn(k, v)
|
||||
}
|
||||
for k, v := range m {
|
||||
fn(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Filter returns a new Mapper containing only the key-value pairs that satisfy the predicate.
|
||||
func (m Mapper[K, V]) Filter(fn func(K, V) bool) Mapper[K, V] {
|
||||
result := NewMapper[K, V]()
|
||||
if m != nil {
|
||||
for k, v := range m {
|
||||
if fn(k, v) {
|
||||
result[k] = v
|
||||
}
|
||||
for k, v := range m {
|
||||
if fn(k, v) {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
return result
|
||||
@@ -137,10 +133,8 @@ func (m Mapper[K, V]) Filter(fn func(K, V) bool) Mapper[K, V] {
|
||||
// MapValues returns a new Mapper with the same keys but values transformed by the provided function.
|
||||
func (m Mapper[K, V]) MapValues(fn func(V) V) Mapper[K, V] {
|
||||
result := NewMapper[K, V]()
|
||||
if m != nil {
|
||||
for k, v := range m {
|
||||
result[k] = fn(v)
|
||||
}
|
||||
for k, v := range m {
|
||||
result[k] = fn(v)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -148,10 +142,8 @@ func (m Mapper[K, V]) MapValues(fn func(V) V) Mapper[K, V] {
|
||||
// Clone returns a shallow copy of the Mapper.
|
||||
func (m Mapper[K, V]) Clone() Mapper[K, V] {
|
||||
result := NewMapper[K, V]()
|
||||
if m != nil {
|
||||
for k, v := range m {
|
||||
result[k] = v
|
||||
}
|
||||
for k, v := range m {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
9
vendor/github.com/olekukonko/tablewriter/tw/preset.go
generated
vendored
9
vendor/github.com/olekukonko/tablewriter/tw/preset.go
generated
vendored
@@ -10,9 +10,6 @@ var (
|
||||
SeparatorsNone = Separators{ShowHeader: Off, ShowFooter: Off, BetweenRows: Off, BetweenColumns: Off}
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// PaddingDefault represents standard single-space padding on left/right
|
||||
// Equivalent to Padding{Left: " ", Right: " ", Overwrite: true}
|
||||
PaddingDefault = Padding{Left: " ", Right: " ", Overwrite: true}
|
||||
)
|
||||
// PaddingDefault represents standard single-space padding on left/right
|
||||
// Equivalent to Padding{Left: " ", Right: " ", Overwrite: true}
|
||||
var PaddingDefault = Padding{Left: " ", Right: " ", Overwrite: true}
|
||||
|
||||
3
vendor/github.com/olekukonko/tablewriter/tw/renderer.go
generated
vendored
3
vendor/github.com/olekukonko/tablewriter/tw/renderer.go
generated
vendored
@@ -1,8 +1,9 @@
|
||||
package tw
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/ll"
|
||||
"io"
|
||||
|
||||
"github.com/olekukonko/ll"
|
||||
)
|
||||
|
||||
// Renderer defines the interface for rendering tables to an io.Writer.
|
||||
|
||||
39
vendor/github.com/olekukonko/tablewriter/tw/slicer.go
generated
vendored
39
vendor/github.com/olekukonko/tablewriter/tw/slicer.go
generated
vendored
@@ -1,5 +1,7 @@
|
||||
package tw
|
||||
|
||||
import "slices"
|
||||
|
||||
// Slicer is a generic slice type that provides additional methods for slice manipulation.
|
||||
type Slicer[T any] []T
|
||||
|
||||
@@ -69,21 +71,17 @@ func (s Slicer[T]) Last() T {
|
||||
// Each iterates over each element in the slice and calls the provided function.
|
||||
// Does nothing if the slice is nil.
|
||||
func (s Slicer[T]) Each(fn func(T)) {
|
||||
if s != nil {
|
||||
for _, v := range s {
|
||||
fn(v)
|
||||
}
|
||||
for _, v := range s {
|
||||
fn(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Filter returns a new Slicer containing only elements that satisfy the predicate.
|
||||
func (s Slicer[T]) Filter(fn func(T) bool) Slicer[T] {
|
||||
result := NewSlicer[T]()
|
||||
if s != nil {
|
||||
for _, v := range s {
|
||||
if fn(v) {
|
||||
result = result.Append(v)
|
||||
}
|
||||
for _, v := range s {
|
||||
if fn(v) {
|
||||
result = result.Append(v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
@@ -92,33 +90,22 @@ func (s Slicer[T]) Filter(fn func(T) bool) Slicer[T] {
|
||||
// Map returns a new Slicer with each element transformed by the provided function.
|
||||
func (s Slicer[T]) Map(fn func(T) T) Slicer[T] {
|
||||
result := NewSlicer[T]()
|
||||
if s != nil {
|
||||
for _, v := range s {
|
||||
result = result.Append(fn(v))
|
||||
}
|
||||
for _, v := range s {
|
||||
result = result.Append(fn(v))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Contains returns true if the slice contains an element that satisfies the predicate.
|
||||
func (s Slicer[T]) Contains(fn func(T) bool) bool {
|
||||
if s != nil {
|
||||
for _, v := range s {
|
||||
if fn(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
return slices.ContainsFunc(s, fn)
|
||||
}
|
||||
|
||||
// Find returns the first element that satisfies the predicate, along with a boolean indicating if it was found.
|
||||
func (s Slicer[T]) Find(fn func(T) bool) (T, bool) {
|
||||
if s != nil {
|
||||
for _, v := range s {
|
||||
if fn(v) {
|
||||
return v, true
|
||||
}
|
||||
for _, v := range s {
|
||||
if fn(v) {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
var zero T
|
||||
|
||||
35
vendor/github.com/olekukonko/tablewriter/tw/types.go
generated
vendored
35
vendor/github.com/olekukonko/tablewriter/tw/types.go
generated
vendored
@@ -3,9 +3,12 @@
|
||||
package tw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/olekukonko/errors"
|
||||
"bytes"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/errors"
|
||||
) // Custom error handling library
|
||||
|
||||
// Position defines where formatting applies in the table (e.g., header, footer, or rows).
|
||||
@@ -31,6 +34,13 @@ type Formatter interface {
|
||||
Format() string // Returns the formatted string representation
|
||||
}
|
||||
|
||||
// Counter defines an interface that combines io.Writer with a method to retrieve a total.
|
||||
// This is used by the WithCounter option to allow for counting lines, bytes, etc.
|
||||
type Counter interface {
|
||||
io.Writer // It must be a writer to be used in io.MultiWriter.
|
||||
Total() int
|
||||
}
|
||||
|
||||
// Align specifies the text alignment within a table cell.
|
||||
type Align string
|
||||
|
||||
@@ -52,7 +62,7 @@ func (a Alignment) String() string {
|
||||
if i > 0 {
|
||||
str.WriteString("; ")
|
||||
}
|
||||
str.WriteString(fmt.Sprint(i))
|
||||
str.WriteString(strconv.Itoa(i))
|
||||
str.WriteString("=")
|
||||
str.WriteString(string(a))
|
||||
}
|
||||
@@ -157,6 +167,7 @@ type Struct struct {
|
||||
type Behavior struct {
|
||||
AutoHide State // AutoHide determines whether empty columns are hidden. Ignored in streaming mode.
|
||||
TrimSpace State // TrimSpace enables trimming of leading and trailing spaces from cell content.
|
||||
TrimLine State // TrimLine determines whether empty visual lines within a cell are collapsed.
|
||||
|
||||
Header Control // Header specifies control settings for the table header.
|
||||
Footer Control // Footer specifies control settings for the table footer.
|
||||
@@ -212,3 +223,21 @@ func (p Padding) Empty() bool {
|
||||
func (p Padding) Paddable() bool {
|
||||
return !p.Empty() || p.Overwrite
|
||||
}
|
||||
|
||||
// LineCounter is the default implementation of the Counter interface.
|
||||
// It counts the number of newline characters written to it.
|
||||
type LineCounter struct {
|
||||
count int
|
||||
}
|
||||
|
||||
// Write implements the io.Writer interface, counting newlines in the input.
|
||||
// It uses a pointer receiver to modify the internal count.
|
||||
func (lc *LineCounter) Write(p []byte) (n int, err error) {
|
||||
lc.count += bytes.Count(p, []byte{'\n'})
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Total implements the Counter interface, returning the final count.
|
||||
func (lc *LineCounter) Total() int {
|
||||
return lc.count
|
||||
}
|
||||
|
||||
70
vendor/github.com/olekukonko/tablewriter/zoo.go
generated
vendored
70
vendor/github.com/olekukonko/tablewriter/zoo.go
generated
vendored
@@ -3,14 +3,15 @@ package tablewriter
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/olekukonko/errors"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/olekukonko/errors"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
)
|
||||
|
||||
// applyHierarchicalMerges applies hierarchical merges to row content.
|
||||
@@ -542,10 +543,7 @@ func (t *Table) buildCoreCellContexts(line []string, merges map[int]tw.MergeStat
|
||||
// It generates a []string where each element is the padding content for a column, using the specified padChar.
|
||||
func (t *Table) buildPaddingLineContents(padChar string, widths tw.Mapper[int, int], numCols int, merges map[int]tw.MergeState) []string {
|
||||
line := make([]string, numCols)
|
||||
padWidth := twwidth.Width(padChar)
|
||||
if padWidth < 1 {
|
||||
padWidth = 1
|
||||
}
|
||||
padWidth := max(twwidth.Width(padChar), 1)
|
||||
for j := 0; j < numCols; j++ {
|
||||
mergeState := tw.MergeState{}
|
||||
if merges != nil {
|
||||
@@ -582,9 +580,9 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
ctx.numCols, t.config.Behavior.Compact.Merge.Enabled())
|
||||
|
||||
// Initialize width maps
|
||||
//t.headerWidths = tw.NewMapper[int, int]()
|
||||
//t.rowWidths = tw.NewMapper[int, int]()
|
||||
//t.footerWidths = tw.NewMapper[int, int]()
|
||||
// t.headerWidths = tw.NewMapper[int, int]()
|
||||
// t.rowWidths = tw.NewMapper[int, int]()
|
||||
// t.footerWidths = tw.NewMapper[int, int]()
|
||||
|
||||
// Compute content-based widths for each section
|
||||
for _, lines := range ctx.headerLines {
|
||||
@@ -720,7 +718,7 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
twwidth.Width(headerCellPadding.Left) +
|
||||
twwidth.Width(headerCellPadding.Right)
|
||||
currentSumOfColumnWidths := 0
|
||||
workingWidths.Each(func(_ int, w int) { currentSumOfColumnWidths += w })
|
||||
workingWidths.Each(func(_, w int) { currentSumOfColumnWidths += w })
|
||||
numSeparatorsInFullSpan := 0
|
||||
if ctx.numCols > 1 {
|
||||
if t.renderer != nil && t.renderer.Config().Settings.Separators.BetweenColumns.Enabled() {
|
||||
@@ -733,7 +731,7 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
mergedContentString, actualMergedHeaderContentPhysicalWidth, totalCurrentSpanPhysicalWidth)
|
||||
shortfall := actualMergedHeaderContentPhysicalWidth - totalCurrentSpanPhysicalWidth
|
||||
numNonZeroCols := 0
|
||||
workingWidths.Each(func(_ int, w int) {
|
||||
workingWidths.Each(func(_, w int) {
|
||||
if w > 0 {
|
||||
numNonZeroCols++
|
||||
}
|
||||
@@ -744,7 +742,7 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
if numNonZeroCols > 0 && shortfall > 0 {
|
||||
extraPerColumn := int(math.Ceil(float64(shortfall) / float64(numNonZeroCols)))
|
||||
finalSumAfterExpansion := 0
|
||||
workingWidths.Each(func(colIdx int, currentW int) {
|
||||
workingWidths.Each(func(colIdx, currentW int) {
|
||||
if currentW > 0 || (numNonZeroCols == ctx.numCols && ctx.numCols > 0) {
|
||||
newWidth := currentW + extraPerColumn
|
||||
workingWidths.Set(colIdx, newWidth)
|
||||
@@ -782,7 +780,7 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
if t.config.Widths.Global > 0 {
|
||||
ctx.logger.Debugf("Applying global width constraint: %d", t.config.Widths.Global)
|
||||
currentSumOfFinalColWidths := 0
|
||||
finalWidths.Each(func(_ int, w int) { currentSumOfFinalColWidths += w })
|
||||
finalWidths.Each(func(_, w int) { currentSumOfFinalColWidths += w })
|
||||
numSeparators := 0
|
||||
if ctx.numCols > 1 && t.renderer != nil && t.renderer.Config().Settings.Separators.BetweenColumns.Enabled() {
|
||||
numSeparators = (ctx.numCols - 1) * twwidth.Width(t.renderer.Config().Symbols.Column())
|
||||
@@ -790,16 +788,13 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
totalCurrentTablePhysicalWidth := currentSumOfFinalColWidths + numSeparators
|
||||
if totalCurrentTablePhysicalWidth > t.config.Widths.Global {
|
||||
ctx.logger.Debugf("Table width %d exceeds global limit %d. Shrinking.", totalCurrentTablePhysicalWidth, t.config.Widths.Global)
|
||||
targetTotalColumnContentWidth := t.config.Widths.Global - numSeparators
|
||||
if targetTotalColumnContentWidth < 0 {
|
||||
targetTotalColumnContentWidth = 0
|
||||
}
|
||||
targetTotalColumnContentWidth := max(t.config.Widths.Global-numSeparators, 0)
|
||||
if ctx.numCols > 0 && targetTotalColumnContentWidth < ctx.numCols {
|
||||
targetTotalColumnContentWidth = ctx.numCols
|
||||
}
|
||||
hardMinimums := tw.NewMapper[int, int]()
|
||||
sumOfHardMinimums := 0
|
||||
isHeaderContentHardToWrap := !(t.config.Header.Formatting.AutoWrap == tw.WrapNormal || t.config.Header.Formatting.AutoWrap == tw.WrapBreak)
|
||||
isHeaderContentHardToWrap := t.config.Header.Formatting.AutoWrap != tw.WrapNormal && t.config.Header.Formatting.AutoWrap != tw.WrapBreak
|
||||
for i := 0; i < ctx.numCols; i++ {
|
||||
minW := 1
|
||||
if isHeaderContentHardToWrap && len(ctx.headerLines) > 0 {
|
||||
@@ -820,7 +815,7 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
}
|
||||
tempSum := 0
|
||||
scaledHardMinimums := tw.NewMapper[int, int]()
|
||||
hardMinimums.Each(func(colIdx int, currentMinW int) {
|
||||
hardMinimums.Each(func(colIdx, currentMinW int) {
|
||||
scaledMinW := int(math.Round(float64(currentMinW) * scaleFactorMin))
|
||||
if scaledMinW < 1 && targetTotalColumnContentWidth > 0 {
|
||||
scaledMinW = 1
|
||||
@@ -894,31 +889,29 @@ func (t *Table) calculateAndNormalizeWidths(ctx *renderContext) error {
|
||||
if errorInDist < 0 {
|
||||
adj = -1
|
||||
}
|
||||
if !(adj < 0 && w+adj < hardMinimums.Get(colToAdjust)) {
|
||||
if adj >= 0 || w+adj >= hardMinimums.Get(colToAdjust) {
|
||||
finalWidths.Set(colToAdjust, w+adj)
|
||||
} else if adj > 0 {
|
||||
finalWidths.Set(colToAdjust, w+adj)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ctx.numCols > 0 {
|
||||
extraPerCol := remainingWidthToDistribute / ctx.numCols
|
||||
rem := remainingWidthToDistribute % ctx.numCols
|
||||
for i := 0; i < ctx.numCols; i++ {
|
||||
currentW := finalWidths.Get(i)
|
||||
add := extraPerCol
|
||||
if i < rem {
|
||||
add++
|
||||
}
|
||||
finalWidths.Set(i, currentW+add)
|
||||
} else if ctx.numCols > 0 {
|
||||
extraPerCol := remainingWidthToDistribute / ctx.numCols
|
||||
rem := remainingWidthToDistribute % ctx.numCols
|
||||
for i := 0; i < ctx.numCols; i++ {
|
||||
currentW := finalWidths.Get(i)
|
||||
add := extraPerCol
|
||||
if i < rem {
|
||||
add++
|
||||
}
|
||||
finalWidths.Set(i, currentW+add)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finalSumCheck := 0
|
||||
finalWidths.Each(func(idx int, w int) {
|
||||
finalWidths.Each(func(idx, w int) {
|
||||
if w < 1 && targetTotalColumnContentWidth > 0 {
|
||||
finalWidths.Set(idx, 1)
|
||||
} else if w < 0 {
|
||||
@@ -945,10 +938,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
|
||||
if isStreaming {
|
||||
// Existing streaming logic remains unchanged
|
||||
totalColumnWidthFromStream := t.streamWidths.Get(colIdx)
|
||||
if totalColumnWidthFromStream < 0 {
|
||||
totalColumnWidthFromStream = 0
|
||||
}
|
||||
totalColumnWidthFromStream := max(t.streamWidths.Get(colIdx), 0)
|
||||
effectiveContentMaxWidth = totalColumnWidthFromStream - padLeftWidth - padRightWidth
|
||||
if effectiveContentMaxWidth < 1 && totalColumnWidthFromStream > (padLeftWidth+padRightWidth) {
|
||||
effectiveContentMaxWidth = 1
|
||||
@@ -1252,7 +1242,7 @@ func (t *Table) convertCellsToStrings(rowInput interface{}, cellCfg tw.CellConfi
|
||||
var err error
|
||||
|
||||
switch v := rowInput.(type) {
|
||||
//Directly supported slice types
|
||||
// Directly supported slice types
|
||||
case []string:
|
||||
cells = v
|
||||
case []interface{}: // Catches variadic simple types grouped by Append
|
||||
@@ -1338,7 +1328,7 @@ func (t *Table) convertCellsToStrings(rowInput interface{}, cellCfg tw.CellConfi
|
||||
cells[i] = val.String()
|
||||
}
|
||||
|
||||
//Cases for single items that are NOT slices
|
||||
// Cases for single items that are NOT slices
|
||||
// These are now dispatched to convertItemToCells by the default case.
|
||||
// Keeping direct tw.Formatter and fmt.Stringer here could be a micro-optimization
|
||||
// if `rowInput` is *exactly* that type (not a struct implementing it),
|
||||
@@ -1578,7 +1568,7 @@ func (t *Table) processVariadic(elements []any) []any {
|
||||
}
|
||||
|
||||
// toStringLines converts raw cells to formatted lines for table output
|
||||
func (t *Table) toStringLines(row interface{}, config tw.CellConfig) ([][]string, error) {
|
||||
func (t *Table) toStringLines(row any, config tw.CellConfig) ([][]string, error) {
|
||||
cells, err := t.convertCellsToStrings(row, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user