Skip to content

Commit 71769f9

Browse files
committed
Update #258
1 parent d84e196 commit 71769f9

File tree

11 files changed

+170
-166
lines changed

11 files changed

+170
-166
lines changed

cmd/csv2table/csv2table.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func process(r io.Reader) error {
209209
case "markdown":
210210
selectedRenderer = renderer.NewMarkdown(baseRendition)
211211
case "html":
212-
selectedRenderer = renderer.NewHTML(outputTarget, *debug, renderer.HTMLConfig{EscapeContent: true})
212+
selectedRenderer = renderer.NewHTML(renderer.HTMLConfig{EscapeContent: true})
213213
case "svg":
214214
selectedRenderer = renderer.NewSVG(renderer.SVGConfig{FontSize: 12, Padding: 5, Debug: *debug})
215215
case "colorized":

renderer/blueprint.go

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
type Blueprint struct {
1414
config tw.Rendition // Rendering configuration for table borders and symbols
1515
logger *ll.Logger // Logger for debug trace messages
16+
w io.Writer
1617
}
1718

1819
// NewBlueprint creates a new Blueprint instance with optional custom configurations.
@@ -46,7 +47,7 @@ func NewBlueprint(configs ...tw.Rendition) *Blueprint {
4647
}
4748

4849
// Close performs cleanup (no-op in this implementation).
49-
func (f *Blueprint) Close(w io.Writer) error {
50+
func (f *Blueprint) Close() error {
5051
f.logger.Debug("Blueprint.Close() called (no-op).")
5152
return nil
5253
}
@@ -57,24 +58,24 @@ func (f *Blueprint) Config() tw.Rendition {
5758
}
5859

5960
// Footer renders the table footer section with configured formatting.
60-
func (f *Blueprint) Footer(w io.Writer, footers [][]string, ctx tw.Formatting) {
61+
func (f *Blueprint) Footer(footers [][]string, ctx tw.Formatting) {
6162
f.logger.Debugf("Starting Footer render: IsSubRow=%v, Location=%v, Pos=%s", ctx.IsSubRow, ctx.Row.Location, ctx.Row.Position)
6263
// Render the footer line
63-
f.renderLine(w, ctx)
64+
f.renderLine(ctx)
6465
f.logger.Debug("Completed Footer render")
6566
}
6667

6768
// Header renders the table header section with configured formatting.
68-
func (f *Blueprint) Header(w io.Writer, headers [][]string, ctx tw.Formatting) {
69+
func (f *Blueprint) Header(headers [][]string, ctx tw.Formatting) {
6970
f.logger.Debugf("Starting Header render: IsSubRow=%v, Location=%v, Pos=%s, lines=%d, widths=%v",
7071
ctx.IsSubRow, ctx.Row.Location, ctx.Row.Position, len(ctx.Row.Current), ctx.Row.Widths)
7172
// Render the header line
72-
f.renderLine(w, ctx)
73+
f.renderLine(ctx)
7374
f.logger.Debug("Completed Header render")
7475
}
7576

7677
// Line renders a full horizontal row line with junctions and segments.
77-
func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
78+
func (f *Blueprint) Line(ctx tw.Formatting) {
7879
// Initialize junction renderer
7980
jr := NewJunction(JunctionContext{
8081
Symbols: f.config.Symbols,
@@ -107,7 +108,7 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
107108
if prefix != "" || suffix != "" {
108109
line.WriteString(prefix + suffix + tw.NewLine)
109110
totalLineWidth = tw.DisplayWidth(prefix) + tw.DisplayWidth(suffix)
110-
fmt.Fprint(w, line.String())
111+
fmt.Fprint(f.w, line.String())
111112
}
112113
f.logger.Debugf("Line: Handled empty row/widths case (total width %d)", totalLineWidth)
113114
return
@@ -135,7 +136,7 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
135136
line.WriteString(leftBorder)
136137
leftBorderWidth = tw.DisplayWidth(leftBorder)
137138
totalLineWidth += leftBorderWidth
138-
f.logger.Debugf("Line: Left border='%s' (width %d)", leftBorder, leftBorderWidth)
139+
f.logger.Debugf("Line: Left border='%s' (f.width %d)", leftBorder, leftBorderWidth)
139140
}
140141

141142
visibleColIndices := make([]int, 0)
@@ -156,7 +157,7 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
156157
// Adjust colWidth to account for wider borders
157158
adjustedColWidth := colWidth
158159
if f.config.Borders.Left.Enabled() && keyIndex == 0 {
159-
adjustedColWidth -= (leftBorderWidth - tw.DisplayWidth(f.config.Symbols.Column()))
160+
adjustedColWidth -= leftBorderWidth - tw.DisplayWidth(f.config.Symbols.Column())
160161
}
161162
if f.config.Borders.Right.Enabled() && keyIndex == len(visibleColIndices)-1 {
162163
rightBorderWidth := tw.DisplayWidth(jr.RenderRight(currentColIdx))
@@ -170,7 +171,7 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
170171
spaces := strings.Repeat(" ", adjustedColWidth)
171172
line.WriteString(spaces)
172173
totalLineWidth += adjustedColWidth
173-
f.logger.Debugf("Line: Rendered spaces='%s' (width %d) for col %d", spaces, adjustedColWidth, currentColIdx)
174+
f.logger.Debugf("Line: Rendered spaces='%s' (f.width %d) for col %d", spaces, adjustedColWidth, currentColIdx)
174175
} else {
175176
segmentWidth := tw.DisplayWidth(segment)
176177
if segmentWidth == 0 {
@@ -205,7 +206,7 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
205206
}
206207
line.WriteString(repeatedSegment)
207208
totalLineWidth += actualWidth
208-
f.logger.Debugf("Line: Rendered segment='%s' (width %d) for col %d", repeatedSegment, actualWidth, currentColIdx)
209+
f.logger.Debugf("Line: Rendered segment='%s' (f.width %d) for col %d", repeatedSegment, actualWidth, currentColIdx)
209210
}
210211

211212
// Add junction between columns if not the last column
@@ -223,7 +224,7 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
223224
junctionWidth := tw.DisplayWidth(junction)
224225
line.WriteString(junction)
225226
totalLineWidth += junctionWidth
226-
f.logger.Debugf("Line: Junction between %d and %d: '%s' (width %d)", currentColIdx, nextColIdx, junction, junctionWidth)
227+
f.logger.Debugf("Line: Junction between %d and %d: '%s' (f.width %d)", currentColIdx, nextColIdx, junction, junctionWidth)
227228
}
228229
}
229230

@@ -235,12 +236,12 @@ func (f *Blueprint) Line(w io.Writer, ctx tw.Formatting) {
235236
rightBorderWidth = tw.DisplayWidth(rightBorder)
236237
line.WriteString(rightBorder)
237238
totalLineWidth += rightBorderWidth
238-
f.logger.Debugf("Line: Right border='%s' (width %d)", rightBorder, rightBorderWidth)
239+
f.logger.Debugf("Line: Right border='%s' (f.width %d)", rightBorder, rightBorderWidth)
239240
}
240241

241242
// Write the final line
242243
line.WriteString(tw.NewLine)
243-
fmt.Fprint(w, line.String())
244+
fmt.Fprint(f.w, line.String())
244245
f.logger.Debugf("Line rendered: '%s' (total width %d, target %d)", strings.TrimSuffix(line.String(), tw.NewLine), totalLineWidth, targetTotalWidth)
245246
}
246247

@@ -250,17 +251,18 @@ func (f *Blueprint) Logger(logger *ll.Logger) {
250251
}
251252

252253
// Row renders a table data row with configured formatting.
253-
func (f *Blueprint) Row(w io.Writer, row []string, ctx tw.Formatting) {
254+
func (f *Blueprint) Row(row []string, ctx tw.Formatting) {
254255
f.logger.Debugf("Starting Row render: IsSubRow=%v, Location=%v, Pos=%s, hasFooter=%v",
255256
ctx.IsSubRow, ctx.Row.Location, ctx.Row.Position, ctx.HasFooter)
256257

257258
// Render the row line
258-
f.renderLine(w, ctx)
259+
f.renderLine(ctx)
259260
f.logger.Debug("Completed Row render")
260261
}
261262

262263
// Start initializes the rendering process (no-op in this implementation).
263264
func (f *Blueprint) Start(w io.Writer) error {
265+
f.w = w
264266
f.logger.Debug("Blueprint.Start() called (no-op).")
265267
return nil
266268
}
@@ -380,7 +382,7 @@ func (f *Blueprint) formatCell(content string, width int, padding tw.Padding, al
380382
}
381383

382384
// renderLine renders a single line (header, row, or footer) with borders, separators, and merge handling.
383-
func (f *Blueprint) renderLine(w io.Writer, ctx tw.Formatting) {
385+
func (f *Blueprint) renderLine(ctx tw.Formatting) {
384386
// Get sorted column indices
385387
sortedKeys := ctx.Row.Widths.SortedKeys()
386388
numCols := 0
@@ -404,7 +406,7 @@ func (f *Blueprint) renderLine(w io.Writer, ctx tw.Formatting) {
404406
if prefix != "" {
405407
output.WriteString(prefix)
406408
totalLineWidth += tw.DisplayWidth(prefix)
407-
f.logger.Debugf("renderLine: Prefix='%s' (width %d)", prefix, tw.DisplayWidth(prefix))
409+
f.logger.Debugf("renderLine: Prefix='%s' (f.width %d)", prefix, tw.DisplayWidth(prefix))
408410
}
409411

410412
colIndex := 0
@@ -437,7 +439,7 @@ func (f *Blueprint) renderLine(w io.Writer, ctx tw.Formatting) {
437439
if shouldAddSeparator {
438440
output.WriteString(columnSeparator)
439441
totalLineWidth += separatorDisplayWidth
440-
f.logger.Debugf("renderLine: Added separator '%s' before col %d (width %d)", columnSeparator, colIndex, separatorDisplayWidth)
442+
f.logger.Debugf("renderLine: Added separator '%s' before col %d (f.width %d)", columnSeparator, colIndex, separatorDisplayWidth)
441443
} else if colIndex > 0 {
442444
f.logger.Debugf("renderLine: Skipped separator before col %d due to zero-width prev col or HMerge continuation", colIndex)
443445
}
@@ -485,7 +487,7 @@ func (f *Blueprint) renderLine(w io.Writer, ctx tw.Formatting) {
485487
spaces := strings.Repeat(" ", visualWidth)
486488
output.WriteString(spaces)
487489
totalLineWidth += visualWidth
488-
f.logger.Debugf("renderLine: No cell context for col %d, writing %d spaces (width %d)", colIndex, visualWidth, visualWidth)
490+
f.logger.Debugf("renderLine: No cell context for col %d, writing %d spaces (f.width %d)", colIndex, visualWidth, visualWidth)
489491
} else {
490492
f.logger.Debugf("renderLine: No cell context for col %d, visualWidth is 0, writing nothing", colIndex)
491493
}
@@ -540,7 +542,7 @@ func (f *Blueprint) renderLine(w io.Writer, ctx tw.Formatting) {
540542
output.WriteString(formattedCell)
541543
cellWidth := tw.DisplayWidth(formattedCell)
542544
totalLineWidth += cellWidth
543-
f.logger.Debugf("renderLine: Rendered col %d, formattedCell='%s' (width %d), totalLineWidth=%d", colIndex, formattedCell, cellWidth, totalLineWidth)
545+
f.logger.Debugf("renderLine: Rendered col %d, formattedCell='%s' (f.width %d), totalLineWidth=%d", colIndex, formattedCell, cellWidth, totalLineWidth)
544546
}
545547

546548
// Log rendering details
@@ -558,10 +560,10 @@ func (f *Blueprint) renderLine(w io.Writer, ctx tw.Formatting) {
558560
if output.Len() > len(prefix) || f.config.Borders.Right.Enabled() {
559561
output.WriteString(suffix)
560562
totalLineWidth += tw.DisplayWidth(suffix)
561-
f.logger.Debugf("renderLine: Suffix='%s' (width %d)", suffix, tw.DisplayWidth(suffix))
563+
f.logger.Debugf("renderLine: Suffix='%s' (f.width %d)", suffix, tw.DisplayWidth(suffix))
562564
}
563565
output.WriteString(tw.NewLine)
564-
fmt.Fprint(w, output.String())
566+
fmt.Fprint(f.w, output.String())
565567
f.logger.Debugf("renderLine: Final rendered line: '%s' (total width %d)", strings.TrimSuffix(output.String(), tw.NewLine), totalLineWidth)
566568
}
567569

renderer/colorized.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type Colorized struct {
5252
newLine string // Newline character
5353
defaultAlign map[tw.Position]tw.Align // Default alignments for header, row, and footer
5454
logger *ll.Logger // Logger for debug messages
55+
w io.Writer
5556
}
5657

5758
// NewColorized creates a Colorized renderer with the specified configuration, falling back to defaults if none provided.
@@ -134,7 +135,7 @@ func NewColorized(configs ...ColorizedConfig) *Colorized {
134135
}
135136

136137
// Close performs cleanup (no-op in this implementation).
137-
func (c *Colorized) Close(w io.Writer) error {
138+
func (c *Colorized) Close() error {
138139
c.logger.Debug("Colorized.Close() called (no-op).")
139140
return nil
140141
}
@@ -155,7 +156,7 @@ func (c *Colorized) Debug() []string {
155156
}
156157

157158
// Footer renders the table footer with configured colors and formatting.
158-
func (c *Colorized) Footer(w io.Writer, footers [][]string, ctx tw.Formatting) {
159+
func (c *Colorized) Footer(footers [][]string, ctx tw.Formatting) {
159160
c.logger.Debugf("Starting Footer render: IsSubRow=%v, Location=%v, Pos=%s",
160161
ctx.IsSubRow, ctx.Row.Location, ctx.Row.Position)
161162

@@ -166,12 +167,12 @@ func (c *Colorized) Footer(w io.Writer, footers [][]string, ctx tw.Formatting) {
166167
}
167168

168169
// Render the footer line
169-
c.renderLine(w, ctx, footers[0], c.config.Footer)
170+
c.renderLine(ctx, footers[0], c.config.Footer)
170171
c.logger.Debug("Completed Footer render")
171172
}
172173

173174
// Header renders the table header with configured colors and formatting.
174-
func (c *Colorized) Header(w io.Writer, headers [][]string, ctx tw.Formatting) {
175+
func (c *Colorized) Header(headers [][]string, ctx tw.Formatting) {
175176
c.logger.Debugf("Starting Header render: IsSubRow=%v, Location=%v, Pos=%s, lines=%d, widths=%v",
176177
ctx.IsSubRow, ctx.Row.Location, ctx.Row.Position, len(headers), ctx.Row.Widths)
177178

@@ -182,12 +183,12 @@ func (c *Colorized) Header(w io.Writer, headers [][]string, ctx tw.Formatting) {
182183
}
183184

184185
// Render the header line
185-
c.renderLine(w, ctx, headers[0], c.config.Header)
186+
c.renderLine(ctx, headers[0], c.config.Header)
186187
c.logger.Debug("Completed Header render")
187188
}
188189

189190
// Line renders a horizontal row line with colored junctions and segments, skipping zero-width columns.
190-
func (c *Colorized) Line(w io.Writer, ctx tw.Formatting) {
191+
func (c *Colorized) Line(ctx tw.Formatting) {
191192
c.logger.Debugf("Line: Starting with Level=%v, Location=%v, IsSubRow=%v, Widths=%v", ctx.Level, ctx.Row.Location, ctx.IsSubRow, ctx.Row.Widths)
192193

193194
// Initialize junction renderer
@@ -232,7 +233,7 @@ func (c *Colorized) Line(w io.Writer, ctx tw.Formatting) {
232233
}
233234
if prefix != "" || suffix != "" {
234235
line.WriteString(prefix + suffix + tw.NewLine)
235-
fmt.Fprint(w, line.String())
236+
fmt.Fprint(c.w, line.String())
236237
}
237238
c.logger.Debug("Line: Handled empty row/widths case (no effective keys)")
238239
return
@@ -323,7 +324,7 @@ func (c *Colorized) Line(w io.Writer, ctx tw.Formatting) {
323324

324325
// Write the final line
325326
line.WriteString(c.newLine)
326-
fmt.Fprint(w, line.String())
327+
fmt.Fprint(c.w, line.String())
327328
c.logger.Debugf("Line rendered: %s", strings.TrimSuffix(line.String(), c.newLine))
328329
}
329330

@@ -339,7 +340,7 @@ func (c *Colorized) Reset() {
339340
}
340341

341342
// Row renders a table data row with configured colors and formatting.
342-
func (c *Colorized) Row(w io.Writer, row []string, ctx tw.Formatting) {
343+
func (c *Colorized) Row(row []string, ctx tw.Formatting) {
343344
c.logger.Debugf("Starting Row render: IsSubRow=%v, Location=%v, Pos=%s, hasFooter=%v",
344345
ctx.IsSubRow, ctx.Row.Location, ctx.Row.Position, ctx.HasFooter)
345346

@@ -350,12 +351,13 @@ func (c *Colorized) Row(w io.Writer, row []string, ctx tw.Formatting) {
350351
}
351352

352353
// Render the row line
353-
c.renderLine(w, ctx, row, c.config.Column)
354+
c.renderLine(ctx, row, c.config.Column)
354355
c.logger.Debugf("Completed Row render")
355356
}
356357

357358
// Start initializes the rendering process (no-op in this implementation).
358359
func (c *Colorized) Start(w io.Writer) error {
360+
c.w = w
359361
c.logger.Debugf("Colorized.Start() called (no-op).")
360362
return nil
361363
}
@@ -493,7 +495,7 @@ func (c *Colorized) formatCell(content string, width int, padding tw.Padding, al
493495
}
494496

495497
// renderLine renders a single line (header, row, or footer) with colors, handling merges and separators.
496-
func (c *Colorized) renderLine(w io.Writer, ctx tw.Formatting, line []string, tint Tint) {
498+
func (c *Colorized) renderLine(ctx tw.Formatting, line []string, tint Tint) {
497499
// Determine number of columns
498500
numCols := 0
499501
if len(ctx.Row.Current) > 0 {
@@ -685,7 +687,7 @@ func (c *Colorized) renderLine(w io.Writer, ctx tw.Formatting, line []string, ti
685687

686688
// Write the final line
687689
output.WriteString(c.newLine)
688-
fmt.Fprint(w, output.String())
690+
fmt.Fprint(c.w, output.String())
689691
c.logger.Debugf("renderLine: Final rendered line: %s", strings.TrimSuffix(output.String(), c.newLine))
690692
}
691693

0 commit comments

Comments
 (0)