github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/table/table.go (about)

     1  package table
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"unicode/utf8"
     7  
     8  	"github.com/olli-ai/jx/v2/pkg/util"
     9  )
    10  
    11  type Table struct {
    12  	Out          io.Writer
    13  	Rows         [][]string
    14  	ColumnWidths []int
    15  	ColumnAlign  []int
    16  	Separator    string
    17  }
    18  
    19  func CreateTable(out io.Writer) Table {
    20  	return Table{
    21  		Out:       out,
    22  		Separator: " ",
    23  	}
    24  }
    25  
    26  // Clear removes all rows while preserving the layout
    27  func (t *Table) Clear() {
    28  	t.Rows = [][]string{}
    29  }
    30  
    31  // AddRow adds a new row to the table
    32  func (t *Table) AddRow(col ...string) {
    33  	t.Rows = append(t.Rows, col)
    34  }
    35  
    36  func (t *Table) Render() {
    37  	// lets figure out the max widths of each column
    38  	for _, row := range t.Rows {
    39  		for ci, col := range row {
    40  			l := utf8.RuneCountInString(col)
    41  			t.ColumnWidths = ensureArrayCanContain(t.ColumnWidths, ci)
    42  			if l > t.ColumnWidths[ci] {
    43  				t.ColumnWidths[ci] = l
    44  			}
    45  		}
    46  	}
    47  
    48  	out := t.Out
    49  	for _, row := range t.Rows {
    50  		lastColumn := len(row) - 1
    51  		for ci, col := range row {
    52  			if ci > 0 {
    53  				fmt.Fprint(out, t.Separator)
    54  			}
    55  			l := t.ColumnWidths[ci]
    56  			align := t.GetColumnAlign(ci)
    57  			if ci >= lastColumn && align != util.ALIGN_CENTER && align != util.ALIGN_RIGHT {
    58  				fmt.Fprint(out, col)
    59  			} else {
    60  				fmt.Fprint(out, util.Pad(col, " ", l, align))
    61  			}
    62  		}
    63  		fmt.Fprint(out, "\n")
    64  	}
    65  }
    66  
    67  // SetColumnsAligns sets the alignment of the columns
    68  func (t *Table) SetColumnsAligns(colAligns []int) {
    69  	t.ColumnAlign = colAligns
    70  }
    71  
    72  // GetColumnAlign return the column alignment
    73  func (t *Table) GetColumnAlign(i int) int {
    74  	t.ColumnAlign = ensureArrayCanContain(t.ColumnAlign, i)
    75  	return t.ColumnAlign[i]
    76  }
    77  
    78  // SetColumnAlign sets the column alignment for the given column index
    79  func (t *Table) SetColumnAlign(i int, align int) {
    80  	t.ColumnAlign = ensureArrayCanContain(t.ColumnAlign, i)
    81  	t.ColumnAlign[i] = align
    82  }
    83  
    84  func ensureArrayCanContain(array []int, idx int) []int {
    85  	diff := idx + 1 - len(array)
    86  	for i := 0; i < diff; i++ {
    87  		array = append(array, 0)
    88  	}
    89  	return array
    90  }