Skip to content

Commit

Permalink
Merge 8ab074f into 830641e
Browse files Browse the repository at this point in the history
  • Loading branch information
jedib0t committed Aug 18, 2018
2 parents 830641e + 8ab074f commit 89c9a83
Show file tree
Hide file tree
Showing 47 changed files with 6,982 additions and 160 deletions.
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -77,6 +77,8 @@ The following features are all used by the other packages in this project.
- [text/valign.go](text/valign.go)
- Colorize text
- [text/color.go](text/color.go)
- Cursor Movement
- [text/cursor.go](text/cursor.go)
- Format text (convert case for now)
- [text/format.go](text/format.go)

Expand Down
10 changes: 5 additions & 5 deletions progress/render.go
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
"time"

"github.com/jedib0t/go-pretty/util"
"github.com/jedib0t/go-pretty/text"
)

// Render renders the Progress tracker and handles all existing trackers and
Expand Down Expand Up @@ -36,7 +36,7 @@ func (p *Progress) renderTrackers(lastRenderLength int) int {

// move up N times based on the number of active trackers
if len(p.trackersActive) > 0 {
out.WriteString(util.CursorUp.Sprintn(len(p.trackersActive)))
out.WriteString(text.CursorUp.Sprintn(len(p.trackersActive)))
}

// move trackers waiting in queue to the active list
Expand Down Expand Up @@ -83,7 +83,7 @@ func (p *Progress) renderTrackers(lastRenderLength int) int {
}

func (p *Progress) renderTracker(out *strings.Builder, t *Tracker) {
out.WriteString(util.EraseLine.Sprint())
out.WriteString(text.EraseLine.Sprint())

if t.IsDone() {
p.renderTrackerDone(out, t)
Expand All @@ -107,7 +107,7 @@ func (p *Progress) renderTracker(out *strings.Builder, t *Tracker) {
} else if pFinishedDotsFraction == 0 {
pInProgress = ""
}
pFinishedStrLen := util.RuneCountWithoutEscapeSeq(pFinished + pInProgress)
pFinishedStrLen := text.RuneCountWithoutEscapeSeq(pFinished + pInProgress)
if pFinishedStrLen < p.lengthProgress {
pUnfinished = strings.Repeat(p.style.Chars.Unfinished, p.lengthProgress-pFinishedStrLen)
}
Expand All @@ -128,7 +128,7 @@ func (p *Progress) renderTrackerDone(out *strings.Builder, t *Tracker) {

func (p *Progress) renderTrackerProgress(out *strings.Builder, t *Tracker, trackerStr string) {
if p.messageWidth > 0 {
t.Message = util.FixedLengthString(t.Message, p.messageWidth, p.style.Options.SnipIndicator)
t.Message = text.FixedLengthString(t.Message, p.messageWidth, p.style.Options.SnipIndicator)
}

if p.trackerPosition == PositionRight {
Expand Down
9 changes: 4 additions & 5 deletions table/render.go
Expand Up @@ -6,7 +6,6 @@ import (
"unicode/utf8"

"github.com/jedib0t/go-pretty/text"
"github.com/jedib0t/go-pretty/util"
)

// Render renders the Table in a human-readable "pretty" format. Example:
Expand Down Expand Up @@ -82,7 +81,7 @@ func (t *Table) renderColumnAutoIndex(out *strings.Builder, rowNum int, hint ren
if hint.isSeparatorRow {
numChars := t.autoIndexVIndexMaxLength + utf8.RuneCountInString(t.style.Box.PaddingLeft) +
utf8.RuneCountInString(t.style.Box.PaddingRight)
outAutoIndex.WriteString(util.RepeatAndTrim(t.style.Box.MiddleHorizontal, numChars))
outAutoIndex.WriteString(text.RepeatAndTrim(t.style.Box.MiddleHorizontal, numChars))
} else {
outAutoIndex.WriteString(t.style.Box.PaddingLeft)
rowNumStr := fmt.Sprint(rowNum)
Expand Down Expand Up @@ -167,10 +166,10 @@ func (t *Table) renderLine(out *strings.Builder, rowNum int, row rowStr, hint re
// merge the strings.Builder objects if a new one was created earlier
if outLine != out {
outLineStr := outLine.String()
if util.RuneCountWithoutEscapeSeq(outLineStr) > t.allowedRowLength {
if text.RuneCountWithoutEscapeSeq(outLineStr) > t.allowedRowLength {
trimLength := t.allowedRowLength - utf8.RuneCountInString(t.style.Box.UnfinishedRow)
if trimLength > 0 {
out.WriteString(util.TrimTextWithoutEscapeSeq(outLineStr, trimLength))
out.WriteString(text.TrimTextWithoutEscapeSeq(outLineStr, trimLength))
out.WriteString(t.style.Box.UnfinishedRow)
}
} else {
Expand Down Expand Up @@ -230,7 +229,7 @@ func (t *Table) renderRow(out *strings.Builder, rowNum int, row rowStr, hint ren
colMaxLines := 0
rowWrapped := make(rowStr, len(row))
for colIdx, colStr := range row {
rowWrapped[colIdx] = util.WrapText(colStr, t.maxColumnLengths[colIdx])
rowWrapped[colIdx] = text.WrapText(colStr, t.maxColumnLengths[colIdx])
colNumLines := strings.Count(rowWrapped[colIdx], "\n") + 1
if colNumLines > colMaxLines {
colMaxLines = colNumLines
Expand Down
3 changes: 1 addition & 2 deletions table/render_test.go
Expand Up @@ -7,7 +7,6 @@ import (
"testing"

"github.com/jedib0t/go-pretty/text"
"github.com/jedib0t/go-pretty/util"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -42,7 +41,7 @@ func TestTable_Render_AutoIndex(t *testing.T) {
for rowIdx := 0; rowIdx < 10; rowIdx++ {
row := make(Row, 10)
for colIdx := 0; colIdx < 10; colIdx++ {
row[colIdx] = fmt.Sprintf("%s%d", util.AutoIndexColumnID(colIdx), rowIdx+1)
row[colIdx] = fmt.Sprintf("%s%d", AutoIndexColumnID(colIdx), rowIdx+1)
}
tw.AppendRow(row)
}
Expand Down
17 changes: 11 additions & 6 deletions table/table.go
Expand Up @@ -3,11 +3,11 @@ package table
import (
"fmt"
"io"
"reflect"
"strings"
"unicode/utf8"

"github.com/jedib0t/go-pretty/text"
"github.com/jedib0t/go-pretty/util"
)

// Row defines a single row in the Table.
Expand Down Expand Up @@ -247,12 +247,17 @@ func (t *Table) analyzeAndStringify(row Row, isHeader bool, isFooter bool) rowSt
rowOut := make(rowStr, len(row))
for colIdx, col := range row {
// if the column is not a number, keep track of it
if !isHeader && !isFooter && !t.columnIsNonNumeric[colIdx] && !util.IsNumber(col) {
if !isHeader && !isFooter && !t.columnIsNonNumeric[colIdx] && !IsNumber(col) {
t.columnIsNonNumeric[colIdx] = true
}

// convert to a string and store it in the row
colStr := util.AsString(col)
var colStr string
if reflect.TypeOf(col).Kind() == reflect.String {
colStr = col.(string)
} else {
colStr = fmt.Sprint(col)
}
if strings.Contains(colStr, "\t") {
colStr = strings.Replace(colStr, "\t", " ", -1)
}
Expand Down Expand Up @@ -290,7 +295,7 @@ func (t *Table) getAllowedColumnLength(colIdx int) int {
func (t *Table) getAutoIndexColumnIDs() rowStr {
row := make(rowStr, t.numColumns)
for colIdx, maxColumnLength := range t.maxColumnLengths {
row[colIdx] = text.AlignCenter.Apply(util.AutoIndexColumnID(colIdx), maxColumnLength)
row[colIdx] = text.AlignCenter.Apply(AutoIndexColumnID(colIdx), maxColumnLength)
}
return row
}
Expand Down Expand Up @@ -367,7 +372,7 @@ func (t *Table) initForRenderMaxColumnLength() {
var findMaxColumnLengths = func(rows []rowStr) {
for _, row := range rows {
for colIdx, colStr := range row {
longestLineLen := util.GetLongestLineLength(colStr)
longestLineLen := text.GetLongestLineLength(colStr)
if longestLineLen > t.maxColumnLengths[colIdx] {
t.maxColumnLengths[colIdx] = longestLineLen
}
Expand Down Expand Up @@ -395,7 +400,7 @@ func (t *Table) initForRenderRowSeparator() {
for colIdx, maxColumnLength := range t.maxColumnLengths {
maxColumnLength += utf8.RuneCountInString(t.style.Box.PaddingLeft)
maxColumnLength += utf8.RuneCountInString(t.style.Box.PaddingRight)
horizontalSeparatorCol := util.RepeatAndTrim(t.style.Box.MiddleHorizontal, maxColumnLength)
horizontalSeparatorCol := text.RepeatAndTrim(t.style.Box.MiddleHorizontal, maxColumnLength)
t.maxRowLength += maxColumnLength
t.rowSeparator[colIdx] = horizontalSeparatorCol
}
Expand Down
28 changes: 28 additions & 0 deletions table/util.go
@@ -0,0 +1,28 @@
package table

import "reflect"

// AutoIndexColumnID returns a unique Column ID/Name for the given Column Number.
// The functionality is similar to what you get in an Excel spreadsheet w.r.t.
// the Column ID/Name.
func AutoIndexColumnID(colIdx int) string {
charIdx := colIdx % 26
out := string(65 + charIdx)
colIdx = colIdx / 26
if colIdx > 0 {
return AutoIndexColumnID(colIdx-1) + out
}
return out
}

// IsNumber returns true if the argument is a numeric type; false otherwise.
func IsNumber(x interface{}) bool {
switch reflect.TypeOf(x).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
return true
}
return false
}

33 changes: 33 additions & 0 deletions table/util_test.go
@@ -0,0 +1,33 @@
package table

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestAutoIndexColumnID(t *testing.T) {
assert.Equal(t, "A", AutoIndexColumnID(0))
assert.Equal(t, "Z", AutoIndexColumnID(25))
assert.Equal(t, "AA", AutoIndexColumnID(26))
assert.Equal(t, "ZZ", AutoIndexColumnID(701))
assert.Equal(t, "AAA", AutoIndexColumnID(702))
assert.Equal(t, "ZZZ", AutoIndexColumnID(18277))
assert.Equal(t, "AAAA", AutoIndexColumnID(18278))
}

func TestIsNumber(t *testing.T) {
assert.True(t, IsNumber(int(1)))
assert.True(t, IsNumber(int8(1)))
assert.True(t, IsNumber(int16(1)))
assert.True(t, IsNumber(int32(1)))
assert.True(t, IsNumber(int64(1)))
assert.True(t, IsNumber(uint(1)))
assert.True(t, IsNumber(uint8(1)))
assert.True(t, IsNumber(uint16(1)))
assert.True(t, IsNumber(uint32(1)))
assert.True(t, IsNumber(uint64(1)))
assert.True(t, IsNumber(float32(1)))
assert.True(t, IsNumber(float64(1)))
assert.False(t, IsNumber("1"))
}
6 changes: 2 additions & 4 deletions text/align.go
Expand Up @@ -5,8 +5,6 @@ import (
"strconv"
"strings"
"unicode/utf8"

"github.com/jedib0t/go-pretty/util"
)

// Align denotes how text is to be aligned horizontally.
Expand All @@ -30,7 +28,7 @@ const (
func (a Align) Apply(text string, maxLength int) string {
text = a.trimString(text)
sLen := utf8.RuneCountInString(text)
sLenWoE := util.RuneCountWithoutEscapeSeq(text)
sLenWoE := RuneCountWithoutEscapeSeq(text)
numEscChars := sLen - sLenWoE

// now, align the text
Expand Down Expand Up @@ -82,7 +80,7 @@ func (a Align) MarkdownProperty() string {
func (a Align) justifyText(text string, textLength int, maxLength int) string {
// split the text into individual words
wordsUnfiltered := strings.Split(text, " ")
words := util.FilterStrings(wordsUnfiltered, func(item string) bool {
words := FilterStrings(wordsUnfiltered, func(item string) bool {
return item != ""
})
// empty string implies spaces for maxLength
Expand Down
5 changes: 5 additions & 0 deletions text/ansi.go
@@ -0,0 +1,5 @@
package text

// ANSICodesSupported will be true on consoles where ANSI Escape Codes/Sequences
// are supported.
var ANSICodesSupported = areANSICodesSupported()
7 changes: 7 additions & 0 deletions text/ansi_unix.go
@@ -0,0 +1,7 @@
// +build !windows

package text

func areANSICodesSupported() bool {
return true
}
23 changes: 23 additions & 0 deletions text/ansi_windows.go
@@ -0,0 +1,23 @@
// +build windows

package text

import (
"os"

"golang.org/x/sys/windows"
)

func areANSICodesSupported() bool {
outHandle := windows.Handle(os.Stdout.Fd())
var outMode uint32
if err := windows.GetConsoleMode(outHandle, &outMode); err == nil {
if outMode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 {
return true
}
if err := windows.SetConsoleMode(outHandle, outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
return true
}
}
return false
}

0 comments on commit 89c9a83

Please sign in to comment.