build(deps): bump github.com/olekukonko/tablewriter from 1.0.7 to 1.0.8
Bumps [github.com/olekukonko/tablewriter](https://github.com/olekukonko/tablewriter) from 1.0.7 to 1.0.8. - [Commits](https://github.com/olekukonko/tablewriter/compare/v1.0.7...v1.0.8) --- updated-dependencies: - dependency-name: github.com/olekukonko/tablewriter dependency-version: 1.0.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
+37
-34
@@ -2,6 +2,7 @@ package renderer
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
@@ -42,7 +43,7 @@ func NewBlueprint(configs ...tw.Rendition) *Blueprint {
|
||||
// Merge user settings with default settings
|
||||
cfg.Settings = mergeSettings(cfg.Settings, userCfg.Settings)
|
||||
}
|
||||
return &Blueprint{config: cfg}
|
||||
return &Blueprint{config: cfg, logger: ll.New("blueprint")}
|
||||
}
|
||||
|
||||
// Close performs cleanup (no-op in this implementation).
|
||||
@@ -106,7 +107,7 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
}
|
||||
if prefix != tw.Empty || suffix != tw.Empty {
|
||||
line.WriteString(prefix + suffix + tw.NewLine)
|
||||
totalLineWidth = tw.DisplayWidth(prefix) + tw.DisplayWidth(suffix)
|
||||
totalLineWidth = twwidth.Width(prefix) + twwidth.Width(suffix)
|
||||
f.w.Write([]byte(line.String()))
|
||||
}
|
||||
f.logger.Debugf("Line: Handled empty row/widths case (total width %d)", totalLineWidth)
|
||||
@@ -119,13 +120,13 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
targetTotalWidth += ctx.Row.Widths.Get(colIdx)
|
||||
}
|
||||
if f.config.Borders.Left.Enabled() {
|
||||
targetTotalWidth += tw.DisplayWidth(f.config.Symbols.Column())
|
||||
targetTotalWidth += twwidth.Width(f.config.Symbols.Column())
|
||||
}
|
||||
if f.config.Borders.Right.Enabled() {
|
||||
targetTotalWidth += tw.DisplayWidth(f.config.Symbols.Column())
|
||||
targetTotalWidth += twwidth.Width(f.config.Symbols.Column())
|
||||
}
|
||||
if f.config.Settings.Separators.BetweenColumns.Enabled() && len(sortedKeys) > 1 {
|
||||
targetTotalWidth += tw.DisplayWidth(f.config.Symbols.Column()) * (len(sortedKeys) - 1)
|
||||
targetTotalWidth += twwidth.Width(f.config.Symbols.Column()) * (len(sortedKeys) - 1)
|
||||
}
|
||||
|
||||
// Add left border if enabled
|
||||
@@ -133,7 +134,7 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
if f.config.Borders.Left.Enabled() {
|
||||
leftBorder := jr.RenderLeft()
|
||||
line.WriteString(leftBorder)
|
||||
leftBorderWidth = tw.DisplayWidth(leftBorder)
|
||||
leftBorderWidth = twwidth.Width(leftBorder)
|
||||
totalLineWidth += leftBorderWidth
|
||||
f.logger.Debugf("Line: Left border='%s' (f.width %d)", leftBorder, leftBorderWidth)
|
||||
}
|
||||
@@ -156,11 +157,11 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
// Adjust colWidth to account for wider borders
|
||||
adjustedColWidth := colWidth
|
||||
if f.config.Borders.Left.Enabled() && keyIndex == 0 {
|
||||
adjustedColWidth -= leftBorderWidth - tw.DisplayWidth(f.config.Symbols.Column())
|
||||
adjustedColWidth -= leftBorderWidth - twwidth.Width(f.config.Symbols.Column())
|
||||
}
|
||||
if f.config.Borders.Right.Enabled() && keyIndex == len(visibleColIndices)-1 {
|
||||
rightBorderWidth := tw.DisplayWidth(jr.RenderRight(currentColIdx))
|
||||
adjustedColWidth -= rightBorderWidth - tw.DisplayWidth(f.config.Symbols.Column())
|
||||
rightBorderWidth := twwidth.Width(jr.RenderRight(currentColIdx))
|
||||
adjustedColWidth -= rightBorderWidth - twwidth.Width(f.config.Symbols.Column())
|
||||
}
|
||||
if adjustedColWidth < 0 {
|
||||
adjustedColWidth = 0
|
||||
@@ -172,7 +173,7 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
totalLineWidth += adjustedColWidth
|
||||
f.logger.Debugf("Line: Rendered spaces='%s' (f.width %d) for col %d", spaces, adjustedColWidth, currentColIdx)
|
||||
} else {
|
||||
segmentWidth := tw.DisplayWidth(segment)
|
||||
segmentWidth := twwidth.Width(segment)
|
||||
if segmentWidth == 0 {
|
||||
segmentWidth = 1 // Avoid division by zero
|
||||
f.logger.Warnf("Line: Segment='%s' has zero width, using 1", segment)
|
||||
@@ -183,11 +184,11 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
repeat = 1
|
||||
}
|
||||
repeatedSegment := strings.Repeat(segment, repeat)
|
||||
actualWidth := tw.DisplayWidth(repeatedSegment)
|
||||
actualWidth := twwidth.Width(repeatedSegment)
|
||||
if actualWidth > adjustedColWidth {
|
||||
// Truncate if too long
|
||||
repeatedSegment = tw.TruncateString(repeatedSegment, adjustedColWidth)
|
||||
actualWidth = tw.DisplayWidth(repeatedSegment)
|
||||
repeatedSegment = twwidth.Truncate(repeatedSegment, adjustedColWidth)
|
||||
actualWidth = twwidth.Width(repeatedSegment)
|
||||
f.logger.Debugf("Line: Truncated segment='%s' to width %d", repeatedSegment, actualWidth)
|
||||
} else if actualWidth < adjustedColWidth {
|
||||
// Pad with segment character to match adjustedColWidth
|
||||
@@ -195,7 +196,7 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
for i := 0; i < remainingWidth/segmentWidth; i++ {
|
||||
repeatedSegment += segment
|
||||
}
|
||||
actualWidth = tw.DisplayWidth(repeatedSegment)
|
||||
actualWidth = twwidth.Width(repeatedSegment)
|
||||
if actualWidth < adjustedColWidth {
|
||||
repeatedSegment = tw.PadRight(repeatedSegment, tw.Space, adjustedColWidth)
|
||||
actualWidth = adjustedColWidth
|
||||
@@ -214,13 +215,13 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
nextColIdx := visibleColIndices[keyIndex+1]
|
||||
junction := jr.RenderJunction(currentColIdx, nextColIdx)
|
||||
// Use center symbol (❀) or column separator (|) to match data rows
|
||||
if tw.DisplayWidth(junction) != tw.DisplayWidth(f.config.Symbols.Column()) {
|
||||
if twwidth.Width(junction) != twwidth.Width(f.config.Symbols.Column()) {
|
||||
junction = f.config.Symbols.Center()
|
||||
if tw.DisplayWidth(junction) != tw.DisplayWidth(f.config.Symbols.Column()) {
|
||||
if twwidth.Width(junction) != twwidth.Width(f.config.Symbols.Column()) {
|
||||
junction = f.config.Symbols.Column()
|
||||
}
|
||||
}
|
||||
junctionWidth := tw.DisplayWidth(junction)
|
||||
junctionWidth := twwidth.Width(junction)
|
||||
line.WriteString(junction)
|
||||
totalLineWidth += junctionWidth
|
||||
f.logger.Debugf("Line: Junction between %d and %d: '%s' (f.width %d)", currentColIdx, nextColIdx, junction, junctionWidth)
|
||||
@@ -232,7 +233,7 @@ func (f *Blueprint) Line(ctx tw.Formatting) {
|
||||
if f.config.Borders.Right.Enabled() && len(visibleColIndices) > 0 {
|
||||
lastIdx := visibleColIndices[len(visibleColIndices)-1]
|
||||
rightBorder := jr.RenderRight(lastIdx)
|
||||
rightBorderWidth = tw.DisplayWidth(rightBorder)
|
||||
rightBorderWidth = twwidth.Width(rightBorder)
|
||||
line.WriteString(rightBorder)
|
||||
totalLineWidth += rightBorderWidth
|
||||
f.logger.Debugf("Line: Right border='%s' (f.width %d)", rightBorder, rightBorderWidth)
|
||||
@@ -276,7 +277,7 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
content, width, align, padding.Left, padding.Right)
|
||||
|
||||
// Calculate display width of content
|
||||
runeWidth := tw.DisplayWidth(content)
|
||||
runeWidth := twwidth.Width(content)
|
||||
|
||||
// Set default padding characters
|
||||
leftPadChar := padding.Left
|
||||
@@ -292,8 +293,8 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
//}
|
||||
|
||||
// Calculate padding widths
|
||||
padLeftWidth := tw.DisplayWidth(leftPadChar)
|
||||
padRightWidth := tw.DisplayWidth(rightPadChar)
|
||||
padLeftWidth := twwidth.Width(leftPadChar)
|
||||
padRightWidth := twwidth.Width(rightPadChar)
|
||||
|
||||
// Calculate available width for content
|
||||
availableContentWidth := width - padLeftWidth - padRightWidth
|
||||
@@ -304,8 +305,8 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
|
||||
// Truncate content if it exceeds available width
|
||||
if runeWidth > availableContentWidth {
|
||||
content = tw.TruncateString(content, availableContentWidth)
|
||||
runeWidth = tw.DisplayWidth(content)
|
||||
content = twwidth.Truncate(content, availableContentWidth)
|
||||
runeWidth = twwidth.Width(content)
|
||||
f.logger.Debugf("Truncated content to fit %d: '%s' (new width %d)", availableContentWidth, content, runeWidth)
|
||||
}
|
||||
|
||||
@@ -363,10 +364,10 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
}
|
||||
|
||||
output := result.String()
|
||||
finalWidth := tw.DisplayWidth(output)
|
||||
finalWidth := twwidth.Width(output)
|
||||
// Adjust output to match target width
|
||||
if finalWidth > width {
|
||||
output = tw.TruncateString(output, width)
|
||||
output = twwidth.Truncate(output, width)
|
||||
f.logger.Debugf("formatCell: Truncated output to width %d", width)
|
||||
} else if finalWidth < width {
|
||||
output = tw.PadRight(output, tw.Space, width)
|
||||
@@ -374,9 +375,9 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
|
||||
}
|
||||
|
||||
// Log warning if final width doesn't match target
|
||||
if f.logger.Enabled() && tw.DisplayWidth(output) != width {
|
||||
if f.logger.Enabled() && twwidth.Width(output) != width {
|
||||
f.logger.Debugf("formatCell Warning: Final width %d does not match target %d for result '%s'",
|
||||
tw.DisplayWidth(output), width, output)
|
||||
twwidth.Width(output), width, output)
|
||||
}
|
||||
|
||||
f.logger.Debugf("Formatted cell final result: '%s' (target width %d)", output, width)
|
||||
@@ -407,14 +408,14 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
totalLineWidth := 0 // Track total display width
|
||||
if prefix != tw.Empty {
|
||||
output.WriteString(prefix)
|
||||
totalLineWidth += tw.DisplayWidth(prefix)
|
||||
f.logger.Debugf("renderLine: Prefix='%s' (f.width %d)", prefix, tw.DisplayWidth(prefix))
|
||||
totalLineWidth += twwidth.Width(prefix)
|
||||
f.logger.Debugf("renderLine: Prefix='%s' (f.width %d)", prefix, twwidth.Width(prefix))
|
||||
}
|
||||
|
||||
colIndex := 0
|
||||
separatorDisplayWidth := 0
|
||||
if f.config.Settings.Separators.BetweenColumns.Enabled() {
|
||||
separatorDisplayWidth = tw.DisplayWidth(columnSeparator)
|
||||
separatorDisplayWidth = twwidth.Width(columnSeparator)
|
||||
}
|
||||
|
||||
// Process each column
|
||||
@@ -542,7 +543,7 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
formattedCell := f.formatCell(cellData, visualWidth, padding, align)
|
||||
if len(formattedCell) > 0 {
|
||||
output.WriteString(formattedCell)
|
||||
cellWidth := tw.DisplayWidth(formattedCell)
|
||||
cellWidth := twwidth.Width(formattedCell)
|
||||
totalLineWidth += cellWidth
|
||||
f.logger.Debugf("renderLine: Rendered col %d, formattedCell='%s' (f.width %d), totalLineWidth=%d", colIndex, formattedCell, cellWidth, totalLineWidth)
|
||||
}
|
||||
@@ -561,17 +562,19 @@ func (f *Blueprint) renderLine(ctx tw.Formatting) {
|
||||
// Add suffix and adjust total width
|
||||
if output.Len() > len(prefix) || f.config.Borders.Right.Enabled() {
|
||||
output.WriteString(suffix)
|
||||
totalLineWidth += tw.DisplayWidth(suffix)
|
||||
f.logger.Debugf("renderLine: Suffix='%s' (f.width %d)", suffix, tw.DisplayWidth(suffix))
|
||||
totalLineWidth += twwidth.Width(suffix)
|
||||
f.logger.Debugf("renderLine: Suffix='%s' (f.width %d)", suffix, twwidth.Width(suffix))
|
||||
}
|
||||
output.WriteString(tw.NewLine)
|
||||
f.w.Write([]byte(output.String()))
|
||||
f.logger.Debugf("renderLine: Final rendered line: '%s' (total width %d)", strings.TrimSuffix(output.String(), tw.NewLine), totalLineWidth)
|
||||
}
|
||||
|
||||
// Rendition updates the Blueprint's configuration.
|
||||
func (f *Blueprint) Rendition(config tw.Rendition) {
|
||||
f.config = mergeRendition(f.config, config)
|
||||
f.logger.Debugf("Blueprint.Rendition updated. New internal config: %+v", f.config)
|
||||
f.logger.Debugf("Blueprint.Rendition updated. New config: %+v", f.config)
|
||||
|
||||
}
|
||||
|
||||
// Ensure Blueprint implements tw.Renditioning
|
||||
|
||||
+14
-14
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/ll/lh"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
@@ -254,7 +255,7 @@ func (c *Colorized) Line(ctx tw.Formatting) {
|
||||
line.WriteString(strings.Repeat(tw.Space, colWidth))
|
||||
} else {
|
||||
// Calculate how many times to repeat the segment
|
||||
segmentWidth := tw.DisplayWidth(segment)
|
||||
segmentWidth := twwidth.Width(segment)
|
||||
if segmentWidth <= 0 {
|
||||
segmentWidth = 1
|
||||
}
|
||||
@@ -266,7 +267,7 @@ func (c *Colorized) Line(ctx tw.Formatting) {
|
||||
line.WriteString(drawnSegment)
|
||||
|
||||
// Adjust for width discrepancies
|
||||
actualDrawnWidth := tw.DisplayWidth(drawnSegment)
|
||||
actualDrawnWidth := twwidth.Width(drawnSegment)
|
||||
if actualDrawnWidth < colWidth {
|
||||
missingWidth := colWidth - actualDrawnWidth
|
||||
spaces := strings.Repeat(tw.Space, missingWidth)
|
||||
@@ -373,7 +374,7 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
}
|
||||
|
||||
// Calculate visual width of content
|
||||
contentVisualWidth := tw.DisplayWidth(content)
|
||||
contentVisualWidth := twwidth.Width(content)
|
||||
|
||||
// Set default padding characters
|
||||
padLeftCharStr := padding.Left
|
||||
@@ -386,8 +387,8 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
}
|
||||
|
||||
// Calculate padding widths
|
||||
definedPadLeftWidth := tw.DisplayWidth(padLeftCharStr)
|
||||
definedPadRightWidth := tw.DisplayWidth(padRightCharStr)
|
||||
definedPadLeftWidth := twwidth.Width(padLeftCharStr)
|
||||
definedPadRightWidth := twwidth.Width(padRightCharStr)
|
||||
// Calculate available width for content and alignment
|
||||
availableForContentAndAlign := width - definedPadLeftWidth - definedPadRightWidth
|
||||
if availableForContentAndAlign < 0 {
|
||||
@@ -396,8 +397,8 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
|
||||
// Truncate content if it exceeds available width
|
||||
if contentVisualWidth > availableForContentAndAlign {
|
||||
content = tw.TruncateString(content, availableForContentAndAlign)
|
||||
contentVisualWidth = tw.DisplayWidth(content)
|
||||
content = twwidth.Truncate(content, availableForContentAndAlign)
|
||||
contentVisualWidth = twwidth.Width(content)
|
||||
c.logger.Debugf("Truncated content to fit %d: '%s' (new width %d)", availableForContentAndAlign, content, contentVisualWidth)
|
||||
}
|
||||
|
||||
@@ -472,12 +473,12 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
output := sb.String()
|
||||
|
||||
// Adjust output width if necessary
|
||||
currentVisualWidth := tw.DisplayWidth(output)
|
||||
currentVisualWidth := twwidth.Width(output)
|
||||
if currentVisualWidth != width {
|
||||
c.logger.Debugf("formatCell MISMATCH: content='%s', target_w=%d. Calculated parts width = %d. String: '%s'",
|
||||
content, width, currentVisualWidth, output)
|
||||
if currentVisualWidth > width {
|
||||
output = tw.TruncateString(output, width)
|
||||
output = twwidth.Truncate(output, width)
|
||||
} else {
|
||||
paddingSpacesStr := strings.Repeat(tw.Space, width-currentVisualWidth)
|
||||
if len(tint.BG) > 0 {
|
||||
@@ -486,10 +487,10 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
|
||||
output += paddingSpacesStr
|
||||
}
|
||||
}
|
||||
c.logger.Debugf("formatCell Post-Correction: Target %d, New Visual width %d. Output: '%s'", width, tw.DisplayWidth(output), output)
|
||||
c.logger.Debugf("formatCell Post-Correction: Target %d, New Visual width %d. Output: '%s'", width, twwidth.Width(output), output)
|
||||
}
|
||||
|
||||
c.logger.Debugf("Formatted cell final result: '%s' (target width %d, display width %d)", output, width, tw.DisplayWidth(output))
|
||||
c.logger.Debugf("Formatted cell final result: '%s' (target width %d, display width %d)", output, width, twwidth.Width(output))
|
||||
return output
|
||||
}
|
||||
|
||||
@@ -529,7 +530,7 @@ func (c *Colorized) renderLine(ctx tw.Formatting, line []string, tint Tint) {
|
||||
separatorString := tw.Empty
|
||||
if c.config.Settings.Separators.BetweenColumns.Enabled() {
|
||||
separatorString = c.config.Separator.Apply(c.config.Symbols.Column())
|
||||
separatorDisplayWidth = tw.DisplayWidth(c.config.Symbols.Column())
|
||||
separatorDisplayWidth = twwidth.Width(c.config.Symbols.Column())
|
||||
}
|
||||
|
||||
// Process each column
|
||||
@@ -693,8 +694,7 @@ func (c *Colorized) renderLine(ctx tw.Formatting, line []string, tint Tint) {
|
||||
// Rendition updates the parts of ColorizedConfig that correspond to tw.Rendition
|
||||
// by merging the provided newRendition. Color-specific Tints are not modified.
|
||||
func (c *Colorized) Rendition(newRendition tw.Rendition) { // Method name matches interface
|
||||
c.logger.Debug("Colorized.Rendition called. Current B/Sym/Set: B:%+v, Sym:%T, S:%+v. Override: %+v",
|
||||
c.config.Borders, c.config.Symbols, c.config.Settings, newRendition)
|
||||
c.logger.Debug("Colorized.Rendition called. Current B/Sym/Set: B:%+v, Sym:%T, S:%+v. Override: %+v", c.config.Borders, c.config.Symbols, c.config.Settings, newRendition)
|
||||
|
||||
currentRenditionPart := tw.Rendition{
|
||||
Borders: c.config.Borders,
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ func NewHTML(configs ...HTMLConfig) *HTML {
|
||||
tableStarted: false,
|
||||
tbodyStarted: false,
|
||||
tfootStarted: false,
|
||||
logger: ll.New("html"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -2,6 +2,7 @@ package renderer
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
@@ -35,7 +36,7 @@ func NewMarkdown(configs ...tw.Rendition) *Markdown {
|
||||
if len(configs) > 0 {
|
||||
cfg = mergeMarkdownConfig(cfg, configs[0])
|
||||
}
|
||||
return &Markdown{config: cfg}
|
||||
return &Markdown{config: cfg, logger: ll.New("markdown")}
|
||||
}
|
||||
|
||||
// mergeMarkdownConfig combines user-provided config with Markdown defaults, enforcing Markdown-specific settings.
|
||||
@@ -157,7 +158,7 @@ func (m *Markdown) formatCell(content string, width int, align tw.Align, padding
|
||||
//if m.config.Settings.TrimWhitespace.Enabled() {
|
||||
// content = strings.TrimSpace(content)
|
||||
//}
|
||||
contentVisualWidth := tw.DisplayWidth(content)
|
||||
contentVisualWidth := twwidth.Width(content)
|
||||
|
||||
// Use specified padding characters or default to spaces
|
||||
padLeftChar := padding.Left
|
||||
@@ -170,8 +171,8 @@ func (m *Markdown) formatCell(content string, width int, align tw.Align, padding
|
||||
}
|
||||
|
||||
// Calculate padding widths
|
||||
padLeftCharWidth := tw.DisplayWidth(padLeftChar)
|
||||
padRightCharWidth := tw.DisplayWidth(padRightChar)
|
||||
padLeftCharWidth := twwidth.Width(padLeftChar)
|
||||
padRightCharWidth := twwidth.Width(padRightChar)
|
||||
minWidth := tw.Max(3, contentVisualWidth+padLeftCharWidth+padRightCharWidth)
|
||||
targetWidth := tw.Max(width, minWidth)
|
||||
|
||||
@@ -212,7 +213,7 @@ func (m *Markdown) formatCell(content string, width int, align tw.Align, padding
|
||||
result := leftPadStr + content + rightPadStr
|
||||
|
||||
// Adjust width if needed
|
||||
finalWidth := tw.DisplayWidth(result)
|
||||
finalWidth := twwidth.Width(result)
|
||||
if finalWidth != targetWidth {
|
||||
m.logger.Debugf("Markdown formatCell MISMATCH: content='%s', target_w=%d, paddingL='%s', paddingR='%s', align=%s -> result='%s', result_w=%d",
|
||||
content, targetWidth, padding.Left, padding.Right, align, result, finalWidth)
|
||||
@@ -229,9 +230,9 @@ func (m *Markdown) formatCell(content string, width int, align tw.Align, padding
|
||||
result += adjStr
|
||||
}
|
||||
} else {
|
||||
result = tw.TruncateString(result, targetWidth)
|
||||
result = twwidth.Truncate(result, targetWidth)
|
||||
}
|
||||
m.logger.Debugf("Markdown formatCell Corrected: target_w=%d, result='%s', new_w=%d", targetWidth, result, tw.DisplayWidth(result))
|
||||
m.logger.Debugf("Markdown formatCell Corrected: target_w=%d, result='%s', new_w=%d", targetWidth, result, twwidth.Width(result))
|
||||
}
|
||||
|
||||
m.logger.Debugf("Markdown formatCell: content='%s', width=%d, align=%s, paddingL='%s', paddingR='%s' -> '%s' (target %d)",
|
||||
@@ -262,11 +263,11 @@ func (m *Markdown) formatSeparator(width int, align tw.Align) string {
|
||||
}
|
||||
|
||||
result := sb.String()
|
||||
currentLen := tw.DisplayWidth(result)
|
||||
currentLen := twwidth.Width(result)
|
||||
if currentLen < targetWidth {
|
||||
result += strings.Repeat("-", targetWidth-currentLen)
|
||||
} else if currentLen > targetWidth {
|
||||
result = tw.TruncateString(result, targetWidth)
|
||||
result = twwidth.Truncate(result, targetWidth)
|
||||
}
|
||||
|
||||
m.logger.Debugf("Markdown formatSeparator: width=%d, align=%s -> '%s'", width, align, result)
|
||||
@@ -314,7 +315,7 @@ func (m *Markdown) renderMarkdownLine(line []string, ctx tw.Formatting, isHeader
|
||||
output.WriteString(prefix)
|
||||
|
||||
colIndex := 0
|
||||
separatorWidth := tw.DisplayWidth(separator)
|
||||
separatorWidth := twwidth.Width(separator)
|
||||
|
||||
for colIndex < numCols {
|
||||
cellCtx, ok := ctx.Row.Current[colIndex]
|
||||
|
||||
+11
-46
@@ -1,6 +1,7 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
@@ -106,17 +107,9 @@ func (o *Ocean) Header(headers [][]string, ctx tw.Formatting) {
|
||||
if !o.widthsFinalized {
|
||||
o.tryFinalizeWidths(ctx)
|
||||
}
|
||||
// The batch renderer (table.go/renderHeader) will call Line() for the top border
|
||||
// and for the header separator if its main config t.config says so.
|
||||
// So, Ocean.Header should *not* draw these itself when in batch mode.
|
||||
// For true streaming, table.go's streamRenderHeader would make these Line() calls.
|
||||
|
||||
// Decision: Ocean.Header *only* renders header content.
|
||||
// Lines (top border, header separator) are managed by the caller (batch or stream logic in table.go).
|
||||
|
||||
if !o.widthsFinalized {
|
||||
o.logger.Error("Ocean.Header: Cannot render content, widths are not finalized.")
|
||||
// o.headerContentRendered = true; // No, content wasn't rendered.
|
||||
return
|
||||
}
|
||||
|
||||
@@ -133,10 +126,7 @@ func (o *Ocean) Header(headers [][]string, ctx tw.Formatting) {
|
||||
o.headerContentRendered = true
|
||||
} else {
|
||||
o.logger.Debug("Ocean.Header: No actual header content lines to render.")
|
||||
// If header is empty, table.go's renderHeader might still call Line() for the separator.
|
||||
// o.headerContentRendered remains false if no content.
|
||||
}
|
||||
// DO NOT draw the header separator line here. Let table.go's renderHeader or streamRenderHeader call o.Line().
|
||||
}
|
||||
|
||||
func (o *Ocean) Row(row []string, ctx tw.Formatting) {
|
||||
@@ -145,15 +135,6 @@ func (o *Ocean) Row(row []string, ctx tw.Formatting) {
|
||||
if !o.widthsFinalized {
|
||||
o.tryFinalizeWidths(ctx)
|
||||
}
|
||||
// Top border / header separator logic:
|
||||
// If this is the very first output, table.go's batch renderHeader (or streamRenderHeader)
|
||||
// should have already called Line() for top border and header separator.
|
||||
// If Header() was called but rendered no content, table.go's renderHeader would still call Line() for the separator.
|
||||
// If Header() was never called by table.go (e.g. streaming rows directly after Start()),
|
||||
// then table.go's streamAppendRow needs to handle initial lines.
|
||||
|
||||
// Decision: Ocean.Row *only* renders row content.
|
||||
|
||||
if !o.widthsFinalized {
|
||||
o.logger.Error("Ocean.Row: Cannot render content, widths are not finalized.")
|
||||
return
|
||||
@@ -171,11 +152,6 @@ func (o *Ocean) Footer(footers [][]string, ctx tw.Formatting) {
|
||||
o.tryFinalizeWidths(ctx)
|
||||
o.logger.Warn("Ocean.Footer: Widths finalized at Footer stage (unusual).")
|
||||
}
|
||||
// Separator line before footer:
|
||||
// This should be handled by table.go's renderFooter or streamRenderFooter calling o.Line().
|
||||
|
||||
// Decision: Ocean.Footer *only* renders footer content.
|
||||
|
||||
if !o.widthsFinalized {
|
||||
o.logger.Error("Ocean.Footer: Cannot render content, widths are not finalized.")
|
||||
return
|
||||
@@ -194,24 +170,19 @@ func (o *Ocean) Footer(footers [][]string, ctx tw.Formatting) {
|
||||
} else {
|
||||
o.logger.Debug("Ocean.Footer: No actual footer content lines to render.")
|
||||
}
|
||||
// DO NOT draw the bottom border here. Let table.go's main Close or batch renderFooter call o.Line().
|
||||
}
|
||||
|
||||
func (o *Ocean) Line(ctx tw.Formatting) {
|
||||
// This method is now called EXTERNALLY by table.go's batch or stream logic
|
||||
// to draw all horizontal lines (top border, header sep, footer sep, bottom border).
|
||||
if !o.widthsFinalized {
|
||||
// If Line is called before widths are known (e.g. table.go's batch renderHeader trying to draw top border)
|
||||
// we must try to finalize widths from this context.
|
||||
o.tryFinalizeWidths(ctx)
|
||||
if !o.widthsFinalized {
|
||||
o.logger.Error("Ocean.Line: Called but widths could not be finalized. Skipping line rendering.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure Line uses the consistent fixedWidths for drawing
|
||||
ctx.Row.Widths = o.fixedWidths
|
||||
|
||||
o.logger.Debugf("Ocean.Line DRAWING: Level=%v, Loc=%s, Pos=%s, IsSubRow=%t, WidthsLen=%d", ctx.Level, ctx.Row.Location, ctx.Row.Position, ctx.IsSubRow, ctx.Row.Widths.Len())
|
||||
|
||||
jr := NewJunction(JunctionContext{
|
||||
@@ -262,7 +233,7 @@ func (o *Ocean) Line(ctx tw.Formatting) {
|
||||
if segmentChar == tw.Empty {
|
||||
segmentChar = o.config.Symbols.Row()
|
||||
}
|
||||
segmentDisplayWidth := tw.DisplayWidth(segmentChar)
|
||||
segmentDisplayWidth := twwidth.Width(segmentChar)
|
||||
if segmentDisplayWidth <= 0 {
|
||||
segmentDisplayWidth = 1
|
||||
}
|
||||
@@ -296,12 +267,6 @@ func (o *Ocean) Line(ctx tw.Formatting) {
|
||||
|
||||
func (o *Ocean) Close() error {
|
||||
o.logger.Debug("Ocean.Close() called.")
|
||||
// The actual bottom border drawing is expected to be handled by table.go's
|
||||
// batch render logic (renderFooter) or stream logic (streamRenderBottomBorder)
|
||||
// by making an explicit call to o.Line() with the correct context.
|
||||
// Ocean.Close() itself does not draw the bottom border to avoid duplication.
|
||||
|
||||
// Only reset state.
|
||||
o.resetState()
|
||||
return nil
|
||||
}
|
||||
@@ -374,7 +339,7 @@ func (o *Ocean) renderContentLine(ctx tw.Formatting, lineData []string) {
|
||||
}
|
||||
|
||||
if k < hSpan-1 && o.config.Settings.Separators.BetweenColumns.Enabled() {
|
||||
currentMergeTotalRenderWidth += tw.DisplayWidth(o.config.Symbols.Column())
|
||||
currentMergeTotalRenderWidth += twwidth.Width(o.config.Symbols.Column())
|
||||
}
|
||||
}
|
||||
actualCellWidthToRender = currentMergeTotalRenderWidth
|
||||
@@ -428,7 +393,7 @@ func (o *Ocean) formatCellContent(content string, cellVisualWidth int, padding t
|
||||
return tw.Empty
|
||||
}
|
||||
|
||||
contentDisplayWidth := tw.DisplayWidth(content)
|
||||
contentDisplayWidth := twwidth.Width(content)
|
||||
|
||||
padLeftChar := padding.Left
|
||||
if padLeftChar == tw.Empty {
|
||||
@@ -439,8 +404,8 @@ func (o *Ocean) formatCellContent(content string, cellVisualWidth int, padding t
|
||||
padRightChar = tw.Space
|
||||
}
|
||||
|
||||
padLeftDisplayWidth := tw.DisplayWidth(padLeftChar)
|
||||
padRightDisplayWidth := tw.DisplayWidth(padRightChar)
|
||||
padLeftDisplayWidth := twwidth.Width(padLeftChar)
|
||||
padRightDisplayWidth := twwidth.Width(padRightChar)
|
||||
|
||||
spaceForContentAndAlignment := cellVisualWidth - padLeftDisplayWidth - padRightDisplayWidth
|
||||
if spaceForContentAndAlignment < 0 {
|
||||
@@ -448,8 +413,8 @@ func (o *Ocean) formatCellContent(content string, cellVisualWidth int, padding t
|
||||
}
|
||||
|
||||
if contentDisplayWidth > spaceForContentAndAlignment {
|
||||
content = tw.TruncateString(content, spaceForContentAndAlignment)
|
||||
contentDisplayWidth = tw.DisplayWidth(content)
|
||||
content = twwidth.Truncate(content, spaceForContentAndAlignment)
|
||||
contentDisplayWidth = twwidth.Width(content)
|
||||
}
|
||||
|
||||
remainingSpace := spaceForContentAndAlignment - contentDisplayWidth
|
||||
@@ -477,7 +442,7 @@ func (o *Ocean) formatCellContent(content string, cellVisualWidth int, padding t
|
||||
sb.WriteString(PR)
|
||||
sb.WriteString(padRightChar)
|
||||
|
||||
currentFormattedWidth := tw.DisplayWidth(sb.String())
|
||||
currentFormattedWidth := twwidth.Width(sb.String())
|
||||
if currentFormattedWidth < cellVisualWidth {
|
||||
if align == tw.AlignRight {
|
||||
prefixSpaces := strings.Repeat(tw.Space, cellVisualWidth-currentFormattedWidth)
|
||||
@@ -490,7 +455,7 @@ func (o *Ocean) formatCellContent(content string, cellVisualWidth int, padding t
|
||||
} else if currentFormattedWidth > cellVisualWidth {
|
||||
tempStr := sb.String()
|
||||
sb.Reset()
|
||||
sb.WriteString(tw.TruncateString(tempStr, cellVisualWidth))
|
||||
sb.WriteString(twwidth.Truncate(tempStr, cellVisualWidth))
|
||||
o.logger.Warnf("formatCellContent: Final string '%s' (width %d) exceeded target %d. Force truncated.", tempStr, currentFormattedWidth, cellVisualWidth)
|
||||
}
|
||||
return sb.String()
|
||||
|
||||
+1
@@ -138,6 +138,7 @@ func NewSVG(configs ...SVGConfig) *SVG {
|
||||
allVisualLineData: make([][][]string, 3),
|
||||
allVisualLineCtx: make([][]tw.Formatting, 3),
|
||||
vMergeTrack: make(map[int]int),
|
||||
logger: ll.New("svg"),
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
r.allVisualLineData[i] = make([][]string, 0)
|
||||
|
||||
Reference in New Issue
Block a user