func visibleSize(s string) (int, error) {
	r := strings.NewReader(s)
	var size int
	for range s {
		_, runeSize, err := r.ReadRune()
		if err != nil {
			return -1, fmt.Errorf("error when calculating visible size of: %s", s)
		}
		if runeSize == 3 {
			size += 2  
		} else {
			size++
		}
	}
	return size, nil
}
visibleSize returns the number of columns the string will cover
when displayed in the terminal. This is the number of runes,
i.e. characters, not the number of bytes it consists of.
package terminal
import (
	"bytes"
	"fmt"
	"io"
	"strings"
)
type Table struct {
	ui            UI
	headers       []string
	headerPrinted bool
	columnWidth   []int
	rowHeight     []int
	rows          [][]string
	colSpacing    string
	transformer   []Transformer
}
type Transformer func(s string) string
func NewTable(headers []string) *Table {
	pt := &Table{
		headers:     headers,
		columnWidth: make([]int, len(headers)),
		colSpacing:  "   ",
		transformer: make([]Transformer, len(headers)),
	}
	for i := range pt.transformer {
		pt.transformer[i] = nop
	}
	if 0 < len(headers) {
		pt.transformer[0] = TableContentHeaderColor
	}
	return pt
}
func (t *Table) NoHeaders() {
	t.headerPrinted = true
}
func (t *Table) SetTransformer(columnIndex int, tr Transformer) {
	t.transformer[columnIndex] = tr
}
func (t *Table) Add(row ...string) {
	t.rows = append(t.rows, row)
}
func (t *Table) PrintTo(result io.Writer) error {
	t.rowHeight = make([]int, len(t.rows)+1)
	rowIndex := 0
	if !t.headerPrinted {
		err := t.calculateMaxSize(transHeader, rowIndex, t.headers)
		if err != nil {
			return err
		}
		rowIndex++
	}
	for _, row := range t.rows {
		err := t.calculateMaxSize(t, rowIndex, row)
		if err != nil {
			return err
		}
		rowIndex++
	}
	rowIndex = 0
	if !t.headerPrinted {
		err := t.printRow(result, transHeader, rowIndex, t.headers)
		if err != nil {
			return err
		}
		t.headerPrinted = true
		rowIndex++
	}
	for row := range t.rows {
		err := t.printRow(result, t, rowIndex, t.rows[row])
		if err != nil {
			return err
		}
		rowIndex++
	}
	t.rows = [][]string{}
	return nil
}
func (t *Table) calculateMaxSize(transformer rowTransformer, rowIndex int, row []string) error {
	for columnIndex := range row {
		if columnIndex >= len(t.headers) {
			break
		}
		lines := strings.Split(row[columnIndex], "\n")
		height := len(lines)
		if t.rowHeight[rowIndex] < height {
			t.rowHeight[rowIndex] = height
		}
		for i := range lines {
			value := trim(Decolorize(transformer.Transform(columnIndex, trim(lines[i]))))
			width, err := visibleSize(value)
			if err != nil {
				return err
			}
			if t.columnWidth[columnIndex] < width {
				t.columnWidth[columnIndex] = width
			}
		}
	}
	return nil
}
func (t *Table) printRow(result io.Writer, transformer rowTransformer, rowIndex int, row []string) error {
	height := t.rowHeight[rowIndex]
	last := len(t.headers) - 1
	lastr := len(row) - 1
	if lastr < last {
		last = lastr
	}
	if height <= 1 {
		line := &bytes.Buffer{}
		for columnIndex := range row {
			if columnIndex >= len(t.headers) {
				break
			}
			err := t.printCellValue(line, transformer, columnIndex, last, row[columnIndex])
			if err != nil {
				return err
			}
		}
		fmt.Fprintf(result, "%s\n", trim(string(line.Bytes())))
		return nil
	}
	sub := make([][]string, len(t.headers))
	for columnIndex := range row {
		if columnIndex >= len(t.headers) {
			break
		}
		sub[columnIndex] = strings.Split(row[columnIndex], "\n")
		for len(sub[columnIndex]) < height {
			sub[columnIndex] = append(sub[columnIndex], "")
		}
	}
	for rowIndex := range sub[0] {
		line := &bytes.Buffer{}
		for columnIndex := range sub {
			err := t.printCellValue(line, transformer, columnIndex, last, sub[columnIndex][rowIndex])
			if err != nil {
				return err
			}
		}
		fmt.Fprintf(result, "%s\n", trim(string(line.Bytes())))
	}
	return nil
}
func (t *Table) printCellValue(result io.Writer, transformer rowTransformer, col, last int, value string) error {
	value = trim(transformer.Transform(col, trim(value)))
	fmt.Fprint(result, value)
	if col < last {
		decolorizedLength, err := visibleSize(trim(Decolorize(value)))
		if err != nil {
			return err
		}
		padlen := t.columnWidth[col] - decolorizedLength
		padding := strings.Repeat(" ", padlen)
		fmt.Fprint(result, padding)
		fmt.Fprint(result, t.colSpacing)
	}
	return nil
}
type rowTransformer interface {
	Transform(column int, s string) string
}
type transformHeader struct{}
var transHeader = &transformHeader{}
func (th *transformHeader) Transform(column int, s string) string {
	return HeaderColor(s)
}
func (t *Table) Transform(column int, s string) string {
	return t.transformer[column](s)
}
func nop(s string) string {
	return s
}
func trim(s string) string {
	return strings.TrimRight(s, " \t")
}