aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/olekukonko/tablewriter/LICENSE.md (renamed from vendor/github.com/olekukonko/tablewriter/LICENCE.md)2
-rw-r--r--vendor/github.com/olekukonko/tablewriter/README.md123
-rw-r--r--vendor/github.com/olekukonko/tablewriter/table.go440
-rw-r--r--vendor/github.com/olekukonko/tablewriter/table_with_color.go134
-rw-r--r--vendor/github.com/olekukonko/tablewriter/test.csv4
-rw-r--r--vendor/github.com/olekukonko/tablewriter/test_info.csv4
-rw-r--r--vendor/github.com/olekukonko/tablewriter/util.go31
-rw-r--r--vendor/github.com/olekukonko/tablewriter/wrap.go16
8 files changed, 606 insertions, 148 deletions
diff --git a/vendor/github.com/olekukonko/tablewriter/LICENCE.md b/vendor/github.com/olekukonko/tablewriter/LICENSE.md
index 1fd848425..a0769b5c1 100644
--- a/vendor/github.com/olekukonko/tablewriter/LICENCE.md
+++ b/vendor/github.com/olekukonko/tablewriter/LICENSE.md
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE. \ No newline at end of file
+THE SOFTWARE.
diff --git a/vendor/github.com/olekukonko/tablewriter/README.md b/vendor/github.com/olekukonko/tablewriter/README.md
index 805330adc..92d71ed48 100644
--- a/vendor/github.com/olekukonko/tablewriter/README.md
+++ b/vendor/github.com/olekukonko/tablewriter/README.md
@@ -1,11 +1,13 @@
ASCII Table Writer
=========
-[![Build Status](https://travis-ci.org/olekukonko/tablewriter.png?branch=master)](https://travis-ci.org/olekukonko/tablewriter) [![Total views](https://sourcegraph.com/api/repos/github.com/olekukonko/tablewriter/counters/views.png)](https://sourcegraph.com/github.com/olekukonko/tablewriter)
+[![Build Status](https://travis-ci.org/olekukonko/tablewriter.png?branch=master)](https://travis-ci.org/olekukonko/tablewriter)
+[![Total views](https://img.shields.io/sourcegraph/rrc/github.com/olekukonko/tablewriter.svg)](https://sourcegraph.com/github.com/olekukonko/tablewriter)
+[![Godoc](https://godoc.org/github.com/olekukonko/tablewriter?status.svg)](https://godoc.org/github.com/olekukonko/tablewriter)
Generate ASCII table on the fly ... Installation is simple as
- go get github.com/olekukonko/tablewriter
+ go get github.com/olekukonko/tablewriter
#### Features
@@ -22,7 +24,8 @@ Generate ASCII table on the fly ... Installation is simple as
- Enable or disable table border
- Set custom footer support
- Optional identical cells merging
-
+- Set custom caption
+- Optional reflowing of paragrpahs in multi-line cells.
#### Example 1 - Basic
```go
@@ -75,21 +78,21 @@ table.Render()
```
DATE | DESCRIPTION | CV2 | AMOUNT
-+----------+--------------------------+-------+---------+
+-----------+--------------------------+-------+----------
1/1/2014 | Domain name | 2233 | $10.98
1/1/2014 | January Hosting | 2233 | $54.95
1/4/2014 | February Hosting | 2233 | $51.00
1/4/2014 | February Extra Bandwidth | 2233 | $30.00
-+----------+--------------------------+-------+---------+
+-----------+--------------------------+-------+----------
TOTAL | $146 93
- +-------+---------+
+ --------+----------
```
#### Example 3 - CSV
```go
-table, _ := tablewriter.NewCSV(os.Stdout, "test_info.csv", true)
+table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test_info.csv", true)
table.SetAlignment(tablewriter.ALIGN_LEFT) // Set Alignment
table.Render()
```
@@ -107,12 +110,12 @@ table.Render()
#### Example 4 - Custom Separator
```go
-table, _ := tablewriter.NewCSV(os.Stdout, "test.csv", true)
+table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test.csv", true)
table.SetRowLine(true) // Enable row line
// Change table lines
table.SetCenterSeparator("*")
-table.SetColumnSeparator("‡")
+table.SetColumnSeparator("╪")
table.SetRowSeparator("-")
table.SetAlignment(tablewriter.ALIGN_LEFT)
@@ -132,7 +135,7 @@ table.Render()
*------------*-----------*---------*
```
-##### Example 5 - Markdown Format
+#### Example 5 - Markdown Format
```go
data := [][]string{
[]string{"1/1/2014", "Domain name", "2233", "$10.98"},
@@ -194,11 +197,109 @@ table.Render()
+----------+--------------------------+-------+---------+
```
+
+#### Table with color
+```go
+data := [][]string{
+ []string{"1/1/2014", "Domain name", "2233", "$10.98"},
+ []string{"1/1/2014", "January Hosting", "2233", "$54.95"},
+ []string{"1/4/2014", "February Hosting", "2233", "$51.00"},
+ []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
+}
+
+table := tablewriter.NewWriter(os.Stdout)
+table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
+table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer
+table.SetBorder(false) // Set Border to false
+
+table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor},
+ tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor},
+ tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor},
+ tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor})
+
+table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
+ tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor},
+ tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
+ tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})
+
+table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{},
+ tablewriter.Colors{tablewriter.Bold},
+ tablewriter.Colors{tablewriter.FgHiRedColor})
+
+table.AppendBulk(data)
+table.Render()
+```
+
+#### Table with color Output
+![Table with Color](https://cloud.githubusercontent.com/assets/6460392/21101956/bbc7b356-c0a1-11e6-9f36-dba694746efc.png)
+
+#### Example 6 - Set table caption
+```go
+data := [][]string{
+ []string{"A", "The Good", "500"},
+ []string{"B", "The Very very Bad Man", "288"},
+ []string{"C", "The Ugly", "120"},
+ []string{"D", "The Gopher", "800"},
+}
+
+table := tablewriter.NewWriter(os.Stdout)
+table.SetHeader([]string{"Name", "Sign", "Rating"})
+table.SetCaption(true, "Movie ratings.")
+
+for _, v := range data {
+ table.Append(v)
+}
+table.Render() // Send output
+```
+
+Note: Caption text will wrap with total width of rendered table.
+
+##### Output 6
+```
++------+-----------------------+--------+
+| NAME | SIGN | RATING |
++------+-----------------------+--------+
+| A | The Good | 500 |
+| B | The Very very Bad Man | 288 |
+| C | The Ugly | 120 |
+| D | The Gopher | 800 |
++------+-----------------------+--------+
+Movie ratings.
+```
+
+#### Render table into a string
+
+Instead of rendering the table to `io.Stdout` you can also render it into a string. Go 1.10 introduced the `strings.Builder` type which implements the `io.Writer` interface and can therefore be used for this task. Example:
+
+```go
+package main
+
+import (
+ "strings"
+ "fmt"
+
+ "github.com/olekukonko/tablewriter"
+)
+
+func main() {
+ tableString := &strings.Builder{}
+ table := tablewriter.NewWriter(tableString)
+
+ /*
+ * Code to fill the table
+ */
+
+ table.Render()
+
+ fmt.Println(tableString.String())
+}
+```
+
#### TODO
- ~~Import Directly from CSV~~ - `done`
- ~~Support for `SetFooter`~~ - `done`
- ~~Support for `SetBorder`~~ - `done`
- ~~Support table with uneven rows~~ - `done`
-- Support custom alignment
+- ~~Support custom alignment~~
- General Improvement & Optimisation
- `NewHTML` Parse table from HTML
diff --git a/vendor/github.com/olekukonko/tablewriter/table.go b/vendor/github.com/olekukonko/tablewriter/table.go
index 3314bfba5..3cf09969e 100644
--- a/vendor/github.com/olekukonko/tablewriter/table.go
+++ b/vendor/github.com/olekukonko/tablewriter/table.go
@@ -36,8 +36,8 @@ const (
)
var (
- decimal = regexp.MustCompile(`^-*\d*\.?\d*$`)
- percent = regexp.MustCompile(`^-*\d*\.?\d*$%$`)
+ decimal = regexp.MustCompile(`^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$`)
+ percent = regexp.MustCompile(`^-?\d+\.?\d*$%$`)
)
type Border struct {
@@ -53,10 +53,13 @@ type Table struct {
lines [][][]string
cs map[int]int
rs map[int]int
- headers []string
- footers []string
+ headers [][]string
+ footers [][]string
+ caption bool
+ captionText string
autoFmt bool
autoWrap bool
+ reflowText bool
mW int
pCenter string
pRow string
@@ -72,40 +75,51 @@ type Table struct {
hdrLine bool
borders Border
colSize int
+ headerParams []string
+ columnsParams []string
+ footerParams []string
+ columnsAlign []int
}
// Start New Table
// Take io.Writer Directly
func NewWriter(writer io.Writer) *Table {
t := &Table{
- out: writer,
- rows: [][]string{},
- lines: [][][]string{},
- cs: make(map[int]int),
- rs: make(map[int]int),
- headers: []string{},
- footers: []string{},
- autoFmt: true,
- autoWrap: true,
- mW: MAX_ROW_WIDTH,
- pCenter: CENTER,
- pRow: ROW,
- pColumn: COLUMN,
- tColumn: -1,
- tRow: -1,
- hAlign: ALIGN_DEFAULT,
- fAlign: ALIGN_DEFAULT,
- align: ALIGN_DEFAULT,
- newLine: NEWLINE,
- rowLine: false,
- hdrLine: true,
- borders: Border{Left: true, Right: true, Bottom: true, Top: true},
- colSize: -1}
+ out: writer,
+ rows: [][]string{},
+ lines: [][][]string{},
+ cs: make(map[int]int),
+ rs: make(map[int]int),
+ headers: [][]string{},
+ footers: [][]string{},
+ caption: false,
+ captionText: "Table caption.",
+ autoFmt: true,
+ autoWrap: true,
+ reflowText: true,
+ mW: MAX_ROW_WIDTH,
+ pCenter: CENTER,
+ pRow: ROW,
+ pColumn: COLUMN,
+ tColumn: -1,
+ tRow: -1,
+ hAlign: ALIGN_DEFAULT,
+ fAlign: ALIGN_DEFAULT,
+ align: ALIGN_DEFAULT,
+ newLine: NEWLINE,
+ rowLine: false,
+ hdrLine: true,
+ borders: Border{Left: true, Right: true, Bottom: true, Top: true},
+ colSize: -1,
+ headerParams: []string{},
+ columnsParams: []string{},
+ footerParams: []string{},
+ columnsAlign: []int{}}
return t
}
// Render table output
-func (t Table) Render() {
+func (t *Table) Render() {
if t.borders.Top {
t.printLine(true)
}
@@ -115,20 +129,27 @@ func (t Table) Render() {
} else {
t.printRows()
}
-
if !t.rowLine && t.borders.Bottom {
t.printLine(true)
}
t.printFooter()
+ if t.caption {
+ t.printCaption()
+ }
}
+const (
+ headerRowIdx = -1
+ footerRowIdx = -2
+)
+
// Set table header
func (t *Table) SetHeader(keys []string) {
t.colSize = len(keys)
for i, v := range keys {
- t.parseDimension(v, i, -1)
- t.headers = append(t.headers, v)
+ lines := t.parseDimension(v, i, headerRowIdx)
+ t.headers = append(t.headers, lines)
}
}
@@ -136,8 +157,16 @@ func (t *Table) SetHeader(keys []string) {
func (t *Table) SetFooter(keys []string) {
//t.colSize = len(keys)
for i, v := range keys {
- t.parseDimension(v, i, -1)
- t.footers = append(t.footers, v)
+ lines := t.parseDimension(v, i, footerRowIdx)
+ t.footers = append(t.footers, lines)
+ }
+}
+
+// Set table Caption
+func (t *Table) SetCaption(caption bool, captionText ...string) {
+ t.caption = caption
+ if len(captionText) == 1 {
+ t.captionText = captionText[0]
}
}
@@ -151,11 +180,21 @@ func (t *Table) SetAutoWrapText(auto bool) {
t.autoWrap = auto
}
+// Turn automatic reflowing of multiline text when rewrapping. Default is on (true).
+func (t *Table) SetReflowDuringAutoWrap(auto bool) {
+ t.reflowText = auto
+}
+
// Set the Default column width
func (t *Table) SetColWidth(width int) {
t.mW = width
}
+// Set the minimal width for a column
+func (t *Table) SetColMinWidth(column int, width int) {
+ t.cs[column] = width
+}
+
// Set the Column Separator
func (t *Table) SetColumnSeparator(sep string) {
t.pColumn = sep
@@ -186,6 +225,22 @@ func (t *Table) SetAlignment(align int) {
t.align = align
}
+func (t *Table) SetColumnAlignment(keys []int) {
+ for _, v := range keys {
+ switch v {
+ case ALIGN_CENTER:
+ break
+ case ALIGN_LEFT:
+ break
+ case ALIGN_RIGHT:
+ break
+ default:
+ v = ALIGN_DEFAULT
+ }
+ t.columnsAlign = append(t.columnsAlign, v)
+ }
+}
+
// Set New Line
func (t *Table) SetNewLine(nl string) {
t.newLine = nl
@@ -249,16 +304,44 @@ func (t *Table) AppendBulk(rows [][]string) {
}
}
+// NumLines to get the number of lines
+func (t *Table) NumLines() int {
+ return len(t.lines)
+}
+
+// Clear rows
+func (t *Table) ClearRows() {
+ t.lines = [][][]string{}
+}
+
+// Clear footer
+func (t *Table) ClearFooter() {
+ t.footers = [][]string{}
+}
+
+// Center based on position and border.
+func (t *Table) center(i int) string {
+ if i == -1 && !t.borders.Left {
+ return t.pRow
+ }
+
+ if i == len(t.cs)-1 && !t.borders.Right {
+ return t.pRow
+ }
+
+ return t.pCenter
+}
+
// Print line based on row width
-func (t Table) printLine(nl bool) {
- fmt.Fprint(t.out, t.pCenter)
+func (t *Table) printLine(nl bool) {
+ fmt.Fprint(t.out, t.center(-1))
for i := 0; i < len(t.cs); i++ {
v := t.cs[i]
fmt.Fprintf(t.out, "%s%s%s%s",
t.pRow,
strings.Repeat(string(t.pRow), v),
t.pRow,
- t.pCenter)
+ t.center(i))
}
if nl {
fmt.Fprint(t.out, t.newLine)
@@ -266,7 +349,7 @@ func (t Table) printLine(nl bool) {
}
// Print line based on row width with our without cell separator
-func (t Table) printLineOptionalCellSeparators(nl bool, displayCellSeparator []bool) {
+func (t *Table) printLineOptionalCellSeparators(nl bool, displayCellSeparator []bool) {
fmt.Fprint(t.out, t.pCenter)
for i := 0; i < len(t.cs); i++ {
v := t.cs[i]
@@ -303,43 +386,64 @@ func pad(align int) func(string, string, int) string {
}
// Print heading information
-func (t Table) printHeading() {
+func (t *Table) printHeading() {
// Check if headers is available
if len(t.headers) < 1 {
return
}
- // Check if border is set
- // Replace with space if not set
- fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))
-
// Identify last column
end := len(t.cs) - 1
// Get pad function
padFunc := pad(t.hAlign)
- // Print Heading column
- for i := 0; i <= end; i++ {
- v := t.cs[i]
- h := t.headers[i]
- if t.autoFmt {
- h = Title(h)
+ // Checking for ANSI escape sequences for header
+ is_esc_seq := false
+ if len(t.headerParams) > 0 {
+ is_esc_seq = true
+ }
+
+ // Maximum height.
+ max := t.rs[headerRowIdx]
+
+ // Print Heading
+ for x := 0; x < max; x++ {
+ // Check if border is set
+ // Replace with space if not set
+ fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))
+
+ for y := 0; y <= end; y++ {
+ v := t.cs[y]
+ h := ""
+ if y < len(t.headers) && x < len(t.headers[y]) {
+ h = t.headers[y][x]
+ }
+ if t.autoFmt {
+ h = Title(h)
+ }
+ pad := ConditionString((y == end && !t.borders.Left), SPACE, t.pColumn)
+
+ if is_esc_seq {
+ fmt.Fprintf(t.out, " %s %s",
+ format(padFunc(h, SPACE, v),
+ t.headerParams[y]), pad)
+ } else {
+ fmt.Fprintf(t.out, " %s %s",
+ padFunc(h, SPACE, v),
+ pad)
+ }
}
- pad := ConditionString((i == end && !t.borders.Left), SPACE, t.pColumn)
- fmt.Fprintf(t.out, " %s %s",
- padFunc(h, SPACE, v),
- pad)
+ // Next line
+ fmt.Fprint(t.out, t.newLine)
}
- // Next line
- fmt.Fprint(t.out, t.newLine)
if t.hdrLine {
t.printLine(true)
}
}
// Print heading information
-func (t Table) printFooter() {
+func (t *Table) printFooter() {
// Check if headers is available
if len(t.footers) < 1 {
return
@@ -349,9 +453,6 @@ func (t Table) printFooter() {
if !t.borders.Bottom {
t.printLine(true)
}
- // Check if border is set
- // Replace with space if not set
- fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE))
// Identify last column
end := len(t.cs) - 1
@@ -359,25 +460,56 @@ func (t Table) printFooter() {
// Get pad function
padFunc := pad(t.fAlign)
- // Print Heading column
- for i := 0; i <= end; i++ {
- v := t.cs[i]
- f := t.footers[i]
- if t.autoFmt {
- f = Title(f)
- }
- pad := ConditionString((i == end && !t.borders.Top), SPACE, t.pColumn)
+ // Checking for ANSI escape sequences for header
+ is_esc_seq := false
+ if len(t.footerParams) > 0 {
+ is_esc_seq = true
+ }
- if len(t.footers[i]) == 0 {
- pad = SPACE
+ // Maximum height.
+ max := t.rs[footerRowIdx]
+
+ // Print Footer
+ erasePad := make([]bool, len(t.footers))
+ for x := 0; x < max; x++ {
+ // Check if border is set
+ // Replace with space if not set
+ fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE))
+
+ for y := 0; y <= end; y++ {
+ v := t.cs[y]
+ f := ""
+ if y < len(t.footers) && x < len(t.footers[y]) {
+ f = t.footers[y][x]
+ }
+ if t.autoFmt {
+ f = Title(f)
+ }
+ pad := ConditionString((y == end && !t.borders.Top), SPACE, t.pColumn)
+
+ if erasePad[y] || (x == 0 && len(f) == 0) {
+ pad = SPACE
+ erasePad[y] = true
+ }
+
+ if is_esc_seq {
+ fmt.Fprintf(t.out, " %s %s",
+ format(padFunc(f, SPACE, v),
+ t.footerParams[y]), pad)
+ } else {
+ fmt.Fprintf(t.out, " %s %s",
+ padFunc(f, SPACE, v),
+ pad)
+ }
+
+ //fmt.Fprintf(t.out, " %s %s",
+ // padFunc(f, SPACE, v),
+ // pad)
}
- fmt.Fprintf(t.out, " %s %s",
- padFunc(f, SPACE, v),
- pad)
+ // Next line
+ fmt.Fprint(t.out, t.newLine)
+ //t.printLine(true)
}
- // Next line
- fmt.Fprint(t.out, t.newLine)
- //t.printLine(true)
hasPrinted := false
@@ -385,7 +517,7 @@ func (t Table) printFooter() {
v := t.cs[i]
pad := t.pRow
center := t.pCenter
- length := len(t.footers[i])
+ length := len(t.footers[i][0])
if length > 0 {
hasPrinted = true
@@ -398,6 +530,9 @@ func (t Table) printFooter() {
// Print first junction
if i == 0 {
+ if length > 0 && !t.borders.Left {
+ center = t.pRow
+ }
fmt.Fprint(t.out, center)
}
@@ -405,16 +540,27 @@ func (t Table) printFooter() {
if length == 0 {
pad = SPACE
}
- // Ignore left space of it has printed before
+ // Ignore left space as it has printed before
if hasPrinted || t.borders.Left {
pad = t.pRow
center = t.pCenter
}
+ // Change Center end position
+ if center != SPACE {
+ if i == end && !t.borders.Right {
+ center = t.pRow
+ }
+ }
+
// Change Center start position
if center == SPACE {
- if i < end && len(t.footers[i+1]) != 0 {
- center = t.pCenter
+ if i < end && len(t.footers[i+1][0]) != 0 {
+ if !t.borders.Left {
+ center = t.pRow
+ } else {
+ center = t.pCenter
+ }
}
}
@@ -428,22 +574,53 @@ func (t Table) printFooter() {
}
fmt.Fprint(t.out, t.newLine)
+}
+
+// Print caption text
+func (t Table) printCaption() {
+ width := t.getTableWidth()
+ paragraph, _ := WrapString(t.captionText, width)
+ for linecount := 0; linecount < len(paragraph); linecount++ {
+ fmt.Fprintln(t.out, paragraph[linecount])
+ }
+}
+
+// Calculate the total number of characters in a row
+func (t Table) getTableWidth() int {
+ var chars int
+ for _, v := range t.cs {
+ chars += v
+ }
+
+ // Add chars, spaces, seperators to calculate the total width of the table.
+ // ncols := t.colSize
+ // spaces := ncols * 2
+ // seps := ncols + 1
+ return (chars + (3 * t.colSize) + 2)
}
func (t Table) printRows() {
for i, lines := range t.lines {
t.printRow(lines, i)
}
+}
+func (t *Table) fillAlignment(num int) {
+ if len(t.columnsAlign) < num {
+ t.columnsAlign = make([]int, num)
+ for i := range t.columnsAlign {
+ t.columnsAlign[i] = t.align
+ }
+ }
}
// Print Row Information
// Adjust column alignment based on type
-func (t Table) printRow(columns [][]string, colKey int) {
+func (t *Table) printRow(columns [][]string, rowIdx int) {
// Get Maximum Height
- max := t.rs[colKey]
+ max := t.rs[rowIdx]
total := len(columns)
// TODO Fix uneven col size
@@ -455,9 +632,15 @@ func (t Table) printRow(columns [][]string, colKey int) {
//}
// Pad Each Height
- // pads := []int{}
pads := []int{}
+ // Checking for ANSI escape sequences for columns
+ is_esc_seq := false
+ if len(t.columnsParams) > 0 {
+ is_esc_seq = true
+ }
+ t.fillAlignment(total)
+
for i, line := range columns {
length := len(line)
pad := max - length
@@ -476,9 +659,14 @@ func (t Table) printRow(columns [][]string, colKey int) {
fmt.Fprintf(t.out, SPACE)
str := columns[y][x]
+ // Embedding escape sequence with column value
+ if is_esc_seq {
+ str = format(str, t.columnsParams[y])
+ }
+
// This would print alignment
// Default alignment would use multiple configuration
- switch t.align {
+ switch t.columnsAlign[y] {
case ALIGN_CENTER: //
fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
case ALIGN_RIGHT:
@@ -514,7 +702,7 @@ func (t Table) printRow(columns [][]string, colKey int) {
}
// Print the rows of the table and merge the cells that are identical
-func (t Table) printRowsMergeCells() {
+func (t *Table) printRowsMergeCells() {
var previousLine []string
var displayCellBorder []bool
var tmpWriter bytes.Buffer
@@ -537,14 +725,19 @@ func (t Table) printRowsMergeCells() {
// Print Row Information to a writer and merge identical cells.
// Adjust column alignment based on type
-func (t Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey int, previousLine []string) ([]string, []bool) {
+func (t *Table) printRowMergeCells(writer io.Writer, columns [][]string, rowIdx int, previousLine []string) ([]string, []bool) {
// Get Maximum Height
- max := t.rs[colKey]
+ max := t.rs[rowIdx]
total := len(columns)
// Pad Each Height
pads := []int{}
+ // Checking for ANSI escape sequences for columns
+ is_esc_seq := false
+ if len(t.columnsParams) > 0 {
+ is_esc_seq = true
+ }
for i, line := range columns {
length := len(line)
pad := max - length
@@ -555,6 +748,7 @@ func (t Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey i
}
var displayCellBorder []bool
+ t.fillAlignment(total)
for x := 0; x < max; x++ {
for y := 0; y < total; y++ {
@@ -565,6 +759,11 @@ func (t Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey i
str := columns[y][x]
+ // Embedding escape sequence with column value
+ if is_esc_seq {
+ str = format(str, t.columnsParams[y])
+ }
+
if t.autoMergeCells {
//Store the full line to merge mutli-lines cells
fullLine := strings.Join(columns[y], " ")
@@ -580,7 +779,7 @@ func (t Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey i
// This would print alignment
// Default alignment would use multiple configuration
- switch t.align {
+ switch t.columnsAlign[y] {
case ALIGN_CENTER: //
fmt.Fprintf(writer, "%s", Pad(str, SPACE, t.cs[y]))
case ALIGN_RIGHT:
@@ -613,44 +812,59 @@ func (t Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey i
func (t *Table) parseDimension(str string, colKey, rowKey int) []string {
var (
- raw []string
- max int
+ raw []string
+ maxWidth int
)
- w := DisplayWidth(str)
- // Calculate Width
- // Check if with is grater than maximum width
- if w > t.mW {
- w = t.mW
- }
- // Check if width exists
- v, ok := t.cs[colKey]
- if !ok || v < w || v == 0 {
- t.cs[colKey] = w
+ raw = getLines(str)
+ maxWidth = 0
+ for _, line := range raw {
+ if w := DisplayWidth(line); w > maxWidth {
+ maxWidth = w
+ }
}
- if rowKey == -1 {
- return raw
- }
- // Calculate Height
+ // If wrapping, ensure that all paragraphs in the cell fit in the
+ // specified width.
if t.autoWrap {
- raw, _ = WrapString(str, t.cs[colKey])
- } else {
- raw = getLines(str)
- }
+ // If there's a maximum allowed width for wrapping, use that.
+ if maxWidth > t.mW {
+ maxWidth = t.mW
+ }
- for _, line := range raw {
- if w := DisplayWidth(line); w > max {
- max = w
+ // In the process of doing so, we need to recompute maxWidth. This
+ // is because perhaps a word in the cell is longer than the
+ // allowed maximum width in t.mW.
+ newMaxWidth := maxWidth
+ newRaw := make([]string, 0, len(raw))
+
+ if t.reflowText {
+ // Make a single paragraph of everything.
+ raw = []string{strings.Join(raw, " ")}
+ }
+ for i, para := range raw {
+ paraLines, _ := WrapString(para, maxWidth)
+ for _, line := range paraLines {
+ if w := DisplayWidth(line); w > newMaxWidth {
+ newMaxWidth = w
+ }
+ }
+ if i > 0 {
+ newRaw = append(newRaw, " ")
+ }
+ newRaw = append(newRaw, paraLines...)
}
+ raw = newRaw
+ maxWidth = newMaxWidth
}
- // Make sure the with is the same length as maximum word
- // Important for cases where the width is smaller than maxu word
- if max > t.cs[colKey] {
- t.cs[colKey] = max
+ // Store the new known maximum width.
+ v, ok := t.cs[colKey]
+ if !ok || v < maxWidth || v == 0 {
+ t.cs[colKey] = maxWidth
}
+ // Remember the number of lines for the row printer.
h := len(raw)
v, ok = t.rs[rowKey]
diff --git a/vendor/github.com/olekukonko/tablewriter/table_with_color.go b/vendor/github.com/olekukonko/tablewriter/table_with_color.go
new file mode 100644
index 000000000..5a4a53ec2
--- /dev/null
+++ b/vendor/github.com/olekukonko/tablewriter/table_with_color.go
@@ -0,0 +1,134 @@
+package tablewriter
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+const ESC = "\033"
+const SEP = ";"
+
+const (
+ BgBlackColor int = iota + 40
+ BgRedColor
+ BgGreenColor
+ BgYellowColor
+ BgBlueColor
+ BgMagentaColor
+ BgCyanColor
+ BgWhiteColor
+)
+
+const (
+ FgBlackColor int = iota + 30
+ FgRedColor
+ FgGreenColor
+ FgYellowColor
+ FgBlueColor
+ FgMagentaColor
+ FgCyanColor
+ FgWhiteColor
+)
+
+const (
+ BgHiBlackColor int = iota + 100
+ BgHiRedColor
+ BgHiGreenColor
+ BgHiYellowColor
+ BgHiBlueColor
+ BgHiMagentaColor
+ BgHiCyanColor
+ BgHiWhiteColor
+)
+
+const (
+ FgHiBlackColor int = iota + 90
+ FgHiRedColor
+ FgHiGreenColor
+ FgHiYellowColor
+ FgHiBlueColor
+ FgHiMagentaColor
+ FgHiCyanColor
+ FgHiWhiteColor
+)
+
+const (
+ Normal = 0
+ Bold = 1
+ UnderlineSingle = 4
+ Italic
+)
+
+type Colors []int
+
+func startFormat(seq string) string {
+ return fmt.Sprintf("%s[%sm", ESC, seq)
+}
+
+func stopFormat() string {
+ return fmt.Sprintf("%s[%dm", ESC, Normal)
+}
+
+// Making the SGR (Select Graphic Rendition) sequence.
+func makeSequence(codes []int) string {
+ codesInString := []string{}
+ for _, code := range codes {
+ codesInString = append(codesInString, strconv.Itoa(code))
+ }
+ return strings.Join(codesInString, SEP)
+}
+
+// Adding ANSI escape sequences before and after string
+func format(s string, codes interface{}) string {
+ var seq string
+
+ switch v := codes.(type) {
+
+ case string:
+ seq = v
+ case []int:
+ seq = makeSequence(v)
+ default:
+ return s
+ }
+
+ if len(seq) == 0 {
+ return s
+ }
+ return startFormat(seq) + s + stopFormat()
+}
+
+// Adding header colors (ANSI codes)
+func (t *Table) SetHeaderColor(colors ...Colors) {
+ if t.colSize != len(colors) {
+ panic("Number of header colors must be equal to number of headers.")
+ }
+ for i := 0; i < len(colors); i++ {
+ t.headerParams = append(t.headerParams, makeSequence(colors[i]))
+ }
+}
+
+// Adding column colors (ANSI codes)
+func (t *Table) SetColumnColor(colors ...Colors) {
+ if t.colSize != len(colors) {
+ panic("Number of column colors must be equal to number of headers.")
+ }
+ for i := 0; i < len(colors); i++ {
+ t.columnsParams = append(t.columnsParams, makeSequence(colors[i]))
+ }
+}
+
+// Adding column colors (ANSI codes)
+func (t *Table) SetFooterColor(colors ...Colors) {
+ if len(t.footers) != len(colors) {
+ panic("Number of footer colors must be equal to number of footer.")
+ }
+ for i := 0; i < len(colors); i++ {
+ t.footerParams = append(t.footerParams, makeSequence(colors[i]))
+ }
+}
+
+func Color(colors ...int) []int {
+ return colors
+}
diff --git a/vendor/github.com/olekukonko/tablewriter/test.csv b/vendor/github.com/olekukonko/tablewriter/test.csv
deleted file mode 100644
index 1609327e9..000000000
--- a/vendor/github.com/olekukonko/tablewriter/test.csv
+++ /dev/null
@@ -1,4 +0,0 @@
-first_name,last_name,ssn
-John,Barry,123456
-Kathy,Smith,687987
-Bob,McCornick,3979870 \ No newline at end of file
diff --git a/vendor/github.com/olekukonko/tablewriter/test_info.csv b/vendor/github.com/olekukonko/tablewriter/test_info.csv
deleted file mode 100644
index e4c40e983..000000000
--- a/vendor/github.com/olekukonko/tablewriter/test_info.csv
+++ /dev/null
@@ -1,4 +0,0 @@
-Field,Type,Null,Key,Default,Extra
-user_id,smallint(5),NO,PRI,NULL,auto_increment
-username,varchar(10),NO,,NULL,
-password,varchar(100),NO,,NULL, \ No newline at end of file
diff --git a/vendor/github.com/olekukonko/tablewriter/util.go b/vendor/github.com/olekukonko/tablewriter/util.go
index 2deefbc52..380e7ab35 100644
--- a/vendor/github.com/olekukonko/tablewriter/util.go
+++ b/vendor/github.com/olekukonko/tablewriter/util.go
@@ -30,17 +30,38 @@ func ConditionString(cond bool, valid, inValid string) string {
return inValid
}
+func isNumOrSpace(r rune) bool {
+ return ('0' <= r && r <= '9') || r == ' '
+}
+
// Format Table Header
// Replace _ , . and spaces
func Title(name string) string {
- name = strings.Replace(name, "_", " ", -1)
- name = strings.Replace(name, ".", " ", -1)
+ origLen := len(name)
+ rs := []rune(name)
+ for i, r := range rs {
+ switch r {
+ case '_':
+ rs[i] = ' '
+ case '.':
+ // ignore floating number 0.0
+ if (i != 0 && !isNumOrSpace(rs[i-1])) || (i != len(rs)-1 && !isNumOrSpace(rs[i+1])) {
+ rs[i] = ' '
+ }
+ }
+ }
+ name = string(rs)
name = strings.TrimSpace(name)
+ if len(name) == 0 && origLen > 0 {
+ // Keep at least one character. This is important to preserve
+ // empty lines in multi-line headers/footers.
+ name = " "
+ }
return strings.ToUpper(name)
}
// Pad String
-// Attempts to play string in the center
+// Attempts to place string in the center
func Pad(s, pad string, width int) string {
gap := width - DisplayWidth(s)
if gap > 0 {
@@ -52,7 +73,7 @@ func Pad(s, pad string, width int) string {
}
// Pad String Right position
-// This would pace string at the left side fo the screen
+// This would place string at the left side of the screen
func PadRight(s, pad string, width int) string {
gap := width - DisplayWidth(s)
if gap > 0 {
@@ -62,7 +83,7 @@ func PadRight(s, pad string, width int) string {
}
// Pad String Left position
-// This would pace string at the right side fo the screen
+// This would place string at the right side of the screen
func PadLeft(s, pad string, width int) string {
gap := width - DisplayWidth(s)
if gap > 0 {
diff --git a/vendor/github.com/olekukonko/tablewriter/wrap.go b/vendor/github.com/olekukonko/tablewriter/wrap.go
index 5290fb65a..a092ee1f7 100644
--- a/vendor/github.com/olekukonko/tablewriter/wrap.go
+++ b/vendor/github.com/olekukonko/tablewriter/wrap.go
@@ -10,7 +10,8 @@ package tablewriter
import (
"math"
"strings"
- "unicode/utf8"
+
+ "github.com/mattn/go-runewidth"
)
var (
@@ -27,7 +28,7 @@ func WrapString(s string, lim int) ([]string, int) {
var lines []string
max := 0
for _, v := range words {
- max = len(v)
+ max = runewidth.StringWidth(v)
if max > lim {
lim = max
}
@@ -55,9 +56,9 @@ func WrapWords(words []string, spc, lim, pen int) [][]string {
length := make([][]int, n)
for i := 0; i < n; i++ {
length[i] = make([]int, n)
- length[i][i] = utf8.RuneCountInString(words[i])
+ length[i][i] = runewidth.StringWidth(words[i])
for j := i + 1; j < n; j++ {
- length[i][j] = length[i][j-1] + spc + utf8.RuneCountInString(words[j])
+ length[i][j] = length[i][j-1] + spc + runewidth.StringWidth(words[j])
}
}
nbrk := make([]int, n)
@@ -94,10 +95,5 @@ func WrapWords(words []string, spc, lim, pen int) [][]string {
// getLines decomposes a multiline string into a slice of strings.
func getLines(s string) []string {
- var lines []string
-
- for _, line := range strings.Split(s, nl) {
- lines = append(lines, line)
- }
- return lines
+ return strings.Split(s, nl)
}