diff --git a/go.mod b/go.mod index 9d442ae..2f76874 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/olekukonko/tablewriter go 1.12 -require github.com/mattn/go-runewidth v0.0.10 +require ( + github.com/mattn/go-runewidth v0.0.10 + golang.org/x/net v0.0.0-20221004154528-8021a29435af +) diff --git a/go.sum b/go.sum index b8b450d..97ae2b6 100644 --- a/go.sum +++ b/go.sum @@ -2,3 +2,10 @@ github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRR github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4= +golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/html.go b/html.go new file mode 100644 index 0000000..6229377 --- /dev/null +++ b/html.go @@ -0,0 +1,56 @@ +package tablewriter + +import ( + "io" + "os" + "golang.org/x/net/html" +) + +func NewHTML(writer io.Writer, fileName string, columnNum int) (*Table, error) { + file, err := os.Open(fileName) + + if err != nil { + return &Table{}, err + } + defer file.Close() + + htmlParser := html.NewTokenizer(file) + + var isTh bool + var isTd bool + var depth int + var headings []string + var cellData []string + table := NewWriter(writer) + + for { + tt := htmlParser.Next() + switch { + case tt == html.ErrorToken: + return table, nil + case tt == html.StartTagToken: + t := htmlParser.Token() + isTd = t.Data == "td" + isTh = t.Data == "th" + case tt == html.TextToken: + t := htmlParser.Token() + if isTd { + cellData = append(cellData, t.Data) + depth++ + } + if isTh { + headings = append(headings, t.Data) + depth++ + } + if isTd && depth % columnNum == 0 { + table.Append(cellData) + cellData = nil + } + if isTh && depth % columnNum == 0 { + table.SetHeader(headings) + } + isTd = false + isTh = false + } + } +} \ No newline at end of file diff --git a/table_test.go b/table_test.go index ec3af2a..37e44be 100644 --- a/table_test.go +++ b/table_test.go @@ -55,6 +55,32 @@ func ExampleShort() { // +------+-----------------------+--------+ } +func ExampleWithArray() { + data := [][]string{ + {"A", "The Good", "500"}, + {"B", "The Very very Bad Man", "288"}, + {"C", "The Ugly", "120"}, + {"D", "The Gopher", "800"}, + } + + table := NewWriter(os.Stdout) + table.SetHeader([]string{"Name", "Sign", "Rating"}) + + for _, v := range data { + table.Append(v) + } + table.Render() + + // Output: +------+-----------------------+--------+ + // | NAME | SIGN | RATING | + // +------+-----------------------+--------+ + // | A | The Good | 500 | + // | B | The Very very Bad Man | 288 | + // | C | The Ugly | 120 | + // | D | The Gopher | 800 | + // +------+-----------------------+--------+ +} + func ExampleTable() { data := [][]string{ {"Learn East has computers with adapted keyboards with enlarged print etc", " Some Data ", " Another Data"}, @@ -98,6 +124,83 @@ func ExampleNewCSV() { // *============*===========*=========* } +func ExampleNewHTMLWithHeadings() { + table, _ := NewHTML(os.Stdout, "testdata/test1.html", 4) + table.SetCenterSeparator("*") + table.SetRowSeparator("=") + + table.Render() + + // Output: *=====*========*=====*================================* + // | S/N | NAME | AGE | HOBBIES | + // *=====*========*=====*================================* + // | 1 | Sydney | 20 | Coding, Partying and trolling | + // | | | | on Twitter | + // | 2 | Harith | 21 | Coding, Praying and learning | + // | | | | new things | + // | 3 | Iyanu | 20 | Coding, Arguing and listening | + // | | | | to weird Music | + // | 4 | Seun | 20 | Watching movie and making | + // | | | | money | + // *=====*========*=====*================================* +} + +func ExampleNewHTMLWithoutHeadings() { + table, _ := NewHTML(os.Stdout, "testdata/test3.html", 4) + table.SetCenterSeparator("*") + table.SetRowSeparator("=") + + table.Render() + + //Output: *===*========*====*================================* + // | 1 | Sydney | 20 | Coding, Partying and trolling | + // | | | | on Twitter | + // | 2 | Harith | 21 | Coding, Praying and learning | + // | | | | new things | + // | 3 | Iyanu | 20 | Coding, Arguing and listening | + // | | | | to weird Music | + // | 4 | Seun | 20 | Watching movie and making | + // | | | | money | + // *===*========*====*================================* +} + +func ExampleNewMalHTML() { + // html has some unclosed tags + table, _ := NewHTML(os.Stdout, "testdata/test2.html", 4) + table.SetCenterSeparator("*") + table.SetRowSeparator("=") + + table.Render() + + // Output: *==========*==========*==========*================================* + // | S/N | NAME | AGE | HOBBIES | + // | | | | | + // *==========*==========*==========*================================* + // | 1 | Sydney | 20 | Coding, Partying and trolling | + // | | | | on Twitter | + // | 2 | Harith | 21 | Coding, Praying and learning | + // | | | | new things | + // | 3 | Iyanu | 20 | Coding, Arguing and listening | + // | | | | to weird Music | + // | 4 | Seun | 20 | Watching movie and making | + // | | | | money | + // *==========*==========*==========*================================* +} + +func ExampleNewMalHTML2() { + table, _ := NewHTML(os.Stdout, "testdata/test4.html", 1) + table.SetCenterSeparator("*") + table.SetRowSeparator("=") + + table.Render() + + // Output: *=====* + // | BAR | + // *=====* + // | foo | + // *=====* +} + func ExampleTable_SetUnicodeHV() { data := [][]string{ {"Regular", "regular line", "1"}, diff --git a/testdata/test1.html b/testdata/test1.html new file mode 100644 index 0000000..6631cc8 --- /dev/null +++ b/testdata/test1.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
S/NNameAgeHobbies
1Sydney20Coding, Partying and trolling on Twitter
2Harith21Coding, Praying and learning new things
3Iyanu20Coding, Arguing and listening to weird Music
4Seun20Watching movie and making money
\ No newline at end of file diff --git a/testdata/test2.html b/testdata/test2.html new file mode 100644 index 0000000..4628ba1 --- /dev/null +++ b/testdata/test2.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + +
S/N + Name + Age + Hobbies +
1 + Sydney + 20 + Coding, Partying and trolling on Twitter +
2Harith21Coding, Praying and learning new things
3Iyanu20Coding, Arguing and listening to weird Music
4Seun20Watching movie and making money
\ No newline at end of file diff --git a/testdata/test3.html b/testdata/test3.html new file mode 100644 index 0000000..c3c9145 --- /dev/null +++ b/testdata/test3.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
1Sydney20Coding, Partying and trolling on Twitter
2Harith21Coding, Praying and learning new things
3Iyanu20Coding, Arguing and listening to weird Music
4Seun20Watching movie and making money
\ No newline at end of file diff --git a/testdata/test4.html b/testdata/test4.html new file mode 100644 index 0000000..281cd23 --- /dev/null +++ b/testdata/test4.html @@ -0,0 +1,7 @@ + + foo + + + bar + +