Skip to content

Commit c27402a

Browse files
authored
table: auto expand columns with Style().Size.WidthMin (#335)
1 parent 183dee4 commit c27402a

File tree

7 files changed

+288
-22
lines changed

7 files changed

+288
-22
lines changed

table/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Pretty-print tables into ASCII/Unicode strings.
1313
- Limit the length of
1414
- Rows (`SetAllowedRowLength`)
1515
- Columns (`ColumnConfig.Width*`)
16+
- Auto-size Rows (`Style().Size.WidthMin` and `Style().Size.WidthMax`)
1617
- Page results by a specified number of Lines (`SetPageSize`)
1718
- Alignment - Horizontal & Vertical
1819
- Auto (horizontal) Align (numeric columns aligned Right)

table/render.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func (t *Table) renderLine(out *strings.Builder, row rowStr, hint renderHint) {
185185

186186
// use a brand-new strings.Builder if a row length limit has been set
187187
var outLine *strings.Builder
188-
if t.allowedRowLength > 0 {
188+
if t.style.Size.WidthMax > 0 {
189189
outLine = &strings.Builder{}
190190
} else {
191191
outLine = out
@@ -227,8 +227,8 @@ func (t *Table) renderLine(out *strings.Builder, row rowStr, hint renderHint) {
227227

228228
func (t *Table) renderLineMergeOutputs(out *strings.Builder, outLine *strings.Builder) {
229229
outLineStr := outLine.String()
230-
if text.RuneWidthWithoutEscSequences(outLineStr) > t.allowedRowLength {
231-
trimLength := t.allowedRowLength - utf8.RuneCountInString(t.style.Box.UnfinishedRow)
230+
if text.RuneWidthWithoutEscSequences(outLineStr) > t.style.Size.WidthMax {
231+
trimLength := t.style.Size.WidthMax - utf8.RuneCountInString(t.style.Box.UnfinishedRow)
232232
if trimLength > 0 {
233233
out.WriteString(text.Trim(outLineStr, trimLength))
234234
out.WriteString(t.style.Box.UnfinishedRow)
@@ -385,8 +385,11 @@ func (t *Table) renderTitle(out *strings.Builder) {
385385
colors := t.style.Title.Colors
386386
colorsBorder := t.getBorderColors(renderHint{isTitleRow: true})
387387
rowLength := t.maxRowLength
388-
if t.allowedRowLength != 0 && t.allowedRowLength < rowLength {
389-
rowLength = t.allowedRowLength
388+
if wm := t.style.Size.WidthMax; wm > 0 && wm < rowLength {
389+
rowLength = wm
390+
}
391+
if wm := t.style.Size.WidthMin; wm > 0 && wm > rowLength {
392+
rowLength = wm
390393
}
391394
if t.style.Options.DrawBorder {
392395
lenBorder := rowLength - text.RuneWidthWithoutEscSequences(t.style.Box.TopLeft+t.style.Box.TopRight)

table/render_init.go

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ func (t *Table) initForRender() {
105105

106106
// find the longest continuous line in each column
107107
t.initForRenderColumnLengths()
108+
t.initForRenderMaxRowLength()
109+
t.initForRenderPaddedColumns()
108110

109111
// generate a separator row and calculate maximum row length
110112
t.initForRenderRowSeparator()
@@ -172,6 +174,50 @@ func (t *Table) initForRenderHideColumns() {
172174
t.columnConfigMap = columnConfigMap
173175
}
174176

177+
func (t *Table) initForRenderMaxRowLength() {
178+
t.maxRowLength = 0
179+
if t.autoIndex {
180+
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft)
181+
t.maxRowLength += len(fmt.Sprint(len(t.rows)))
182+
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingRight)
183+
if t.style.Options.SeparateColumns {
184+
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator)
185+
}
186+
}
187+
if t.style.Options.SeparateColumns {
188+
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator) * (t.numColumns - 1)
189+
}
190+
for _, maxColumnLength := range t.maxColumnLengths {
191+
maxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)
192+
t.maxRowLength += maxColumnLength
193+
}
194+
if t.style.Options.DrawBorder {
195+
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)
196+
}
197+
}
198+
199+
func (t *Table) initForRenderPaddedColumns() {
200+
paddingSize := t.style.Size.WidthMin - t.maxRowLength
201+
for paddingSize > 0 {
202+
// distribute padding equally among all columns
203+
numColumnsPadded := 0
204+
for colIdx := 0; paddingSize > 0 && colIdx < t.numColumns; colIdx++ {
205+
colWidthMax := t.getColumnWidthMax(colIdx)
206+
if colWidthMax == 0 || t.maxColumnLengths[colIdx] < colWidthMax {
207+
t.maxColumnLengths[colIdx]++
208+
numColumnsPadded++
209+
paddingSize--
210+
}
211+
}
212+
213+
// avoid endless looping because all columns are at max size and cannot
214+
// be expanded any further
215+
if numColumnsPadded == 0 {
216+
break
217+
}
218+
}
219+
}
220+
175221
func (t *Table) initForRenderRows() {
176222
// auto-index: calc the index column's max length
177223
t.autoIndexVIndexMaxLength = len(fmt.Sprint(len(t.rowsRaw)))
@@ -206,27 +252,11 @@ func (t *Table) initForRenderRowsStringify(rows []Row, hint renderHint) []rowStr
206252
}
207253

208254
func (t *Table) initForRenderRowSeparator() {
209-
t.maxRowLength = 0
210-
if t.autoIndex {
211-
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft)
212-
t.maxRowLength += len(fmt.Sprint(len(t.rows)))
213-
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingRight)
214-
if t.style.Options.SeparateColumns {
215-
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator)
216-
}
217-
}
218-
if t.style.Options.SeparateColumns {
219-
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator) * (t.numColumns - 1)
220-
}
221255
t.rowSeparator = make(rowStr, t.numColumns)
222256
for colIdx, maxColumnLength := range t.maxColumnLengths {
223257
maxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)
224-
t.maxRowLength += maxColumnLength
225258
t.rowSeparator[colIdx] = text.RepeatAndTrim(t.style.Box.MiddleHorizontal, maxColumnLength)
226259
}
227-
if t.style.Options.DrawBorder {
228-
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)
229-
}
230260
}
231261

232262
func (t *Table) initForRenderSortRows() {

0 commit comments

Comments
 (0)