From 77f3d3a799c729225904059d6001aafe3c39943b Mon Sep 17 00:00:00 2001 From: Nelson Isioma <58360242+Nelwhix@users.noreply.github.com> Date: Tue, 11 Oct 2022 02:27:05 +0100 Subject: [PATCH 1/6] adding functionality for NewHTML --- go.mod | 5 +++- go.sum | 7 ++++++ html.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++ testdata/test.html | 32 ++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 html.go create mode 100644 testdata/test.html 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..bc0b08e --- /dev/null +++ b/html.go @@ -0,0 +1,61 @@ +package tablewriter + +import ( + "io" + "os" + "golang.org/x/net/html" +) + +func NewHTML(writer io.Writer, fileName string, hasHeader bool) (*Table, error) { + file, err := os.Open(fileName) + + if err != nil { + return &Table{}, err + } + defer file.Close() + // Parse the html + htmlParser := html.NewTokenizer(file) + + var isTh bool + var isTd bool + var n int + var headings []string + var records []string + table := NewWriter(writer) + + // start a loop tokenizing the html + for { + tt := htmlParser.Next() + switch { + case tt == html.ErrorToken: + return &Table{}, err + // if the token gets to start tag that is td or th, make isTd and isTh true + case tt == html.StartTagToken: + t := htmlParser.Token() + isTd = t.Data == "td" + isTh = t.Data == "th" + case tt == html.TextToken: + t := htmlParser.Token() + if isTd { + records = append(records, t.Data) + n++ + } + if isTh { + headings = append(headings, t.Data) + n++ + } + if isTd && n % 4 == 0 { + table.Append(records) + records = nil + } + isTd = false + isTh = false + } + } + + if hasHeader { + table.SetHeader(headings) + } + + return table, nil +} \ No newline at end of file diff --git a/testdata/test.html b/testdata/test.html new file mode 100644 index 0000000..6631cc8 --- /dev/null +++ b/testdata/test.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 From 4d3ee4e57601e899833020217ee44ee29423771b Mon Sep 17 00:00:00 2001 From: Nelson Isioma <58360242+Nelwhix@users.noreply.github.com> Date: Tue, 11 Oct 2022 13:28:10 +0100 Subject: [PATCH 2/6] making some tweaks --- html.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/html.go b/html.go index bc0b08e..ea6b62d 100644 --- a/html.go +++ b/html.go @@ -6,7 +6,7 @@ import ( "golang.org/x/net/html" ) -func NewHTML(writer io.Writer, fileName string, hasHeader bool) (*Table, error) { +func NewHTML(writer io.Writer, fileName string, headingsNum int) (*Table, error) { file, err := os.Open(fileName) if err != nil { @@ -14,21 +14,22 @@ func NewHTML(writer io.Writer, fileName string, hasHeader bool) (*Table, error) } defer file.Close() // Parse the html - htmlParser := html.NewTokenizer(file) + htmlParser := html.NewTokenizer(file) // file must utf-8 encoded html or error var isTh bool var isTd bool - var n int + var n int // n is the number of th tags in the html file + var depth int var headings []string var records []string table := NewWriter(writer) - + // start a loop tokenizing the html for { tt := htmlParser.Next() switch { case tt == html.ErrorToken: - return &Table{}, err + return &Table{}, nil // if the token gets to start tag that is td or th, make isTd and isTh true case tt == html.StartTagToken: t := htmlParser.Token() @@ -38,24 +39,21 @@ func NewHTML(writer io.Writer, fileName string, hasHeader bool) (*Table, error) t := htmlParser.Token() if isTd { records = append(records, t.Data) - n++ + depth++ } if isTh { headings = append(headings, t.Data) n++ } - if isTd && n % 4 == 0 { + if isTd && depth % headingsNum == 0 { table.Append(records) records = nil } + if isTh && n % headingsNum == 0 { + table.SetHeader(headings) + } isTd = false isTh = false } } - - if hasHeader { - table.SetHeader(headings) - } - - return table, nil } \ No newline at end of file From 9da661a1f1d73f311464dd8287006715f2fc45f3 Mon Sep 17 00:00:00 2001 From: Nelson Isioma <58360242+Nelwhix@users.noreply.github.com> Date: Tue, 11 Oct 2022 21:43:39 +0100 Subject: [PATCH 3/6] fixing --- html.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/html.go b/html.go index ea6b62d..740940e 100644 --- a/html.go +++ b/html.go @@ -14,7 +14,7 @@ func NewHTML(writer io.Writer, fileName string, headingsNum int) (*Table, error) } defer file.Close() // Parse the html - htmlParser := html.NewTokenizer(file) // file must utf-8 encoded html or error + htmlParser := html.NewTokenizer(file) // file must be a utf-8 encoded html or error var isTh bool var isTd bool @@ -30,7 +30,7 @@ func NewHTML(writer io.Writer, fileName string, headingsNum int) (*Table, error) switch { case tt == html.ErrorToken: return &Table{}, nil - // if the token gets to start tag that is td or th, make isTd and isTh true + // if the token gets to a start tag that is td or th, make isTd and isTh true case tt == html.StartTagToken: t := htmlParser.Token() isTd = t.Data == "td" From 18f93a9b81546a030302ebd63ee3413d75f278d8 Mon Sep 17 00:00:00 2001 From: Nelson Isioma <58360242+Nelwhix@users.noreply.github.com> Date: Thu, 19 Jan 2023 00:05:08 +0100 Subject: [PATCH 4/6] added tests for newHTML --- html.go | 2 +- table_test.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/html.go b/html.go index 740940e..ad0c656 100644 --- a/html.go +++ b/html.go @@ -29,7 +29,7 @@ func NewHTML(writer io.Writer, fileName string, headingsNum int) (*Table, error) tt := htmlParser.Next() switch { case tt == html.ErrorToken: - return &Table{}, nil + return table, nil // if the token gets to a start tag that is td or th, make isTd and isTh true case tt == html.StartTagToken: t := htmlParser.Token() diff --git a/table_test.go b/table_test.go index 3a746fb..75c241a 100644 --- a/table_test.go +++ b/table_test.go @@ -98,6 +98,27 @@ func ExampleNewCSV() { // *============*===========*=========* } +func ExampleNewHTML() { + table, _ := NewHTML(os.Stdout, "testdata/test.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 | +// *=====*========*=====*================================* +} + // TestNumLines to test the numbers of lines func TestNumLines(t *testing.T) { data := [][]string{ From 2e15b73575ecee2d3e2c74c3fff5b08d88e6e3ea Mon Sep 17 00:00:00 2001 From: Nelson Isioma <58360242+Nelwhix@users.noreply.github.com> Date: Mon, 23 Jan 2023 06:06:14 +0100 Subject: [PATCH 5/6] adding more tests for newHTML --- html.go | 25 +++++++--------- table_test.go | 46 ++++++++++++++++++++++++++++-- testdata/{test.html => test1.html} | 0 testdata/test2.html | 27 ++++++++++++++++++ testdata/test3.html | 26 +++++++++++++++++ 5 files changed, 108 insertions(+), 16 deletions(-) rename testdata/{test.html => test1.html} (100%) create mode 100644 testdata/test2.html create mode 100644 testdata/test3.html diff --git a/html.go b/html.go index ad0c656..6229377 100644 --- a/html.go +++ b/html.go @@ -6,31 +6,28 @@ import ( "golang.org/x/net/html" ) -func NewHTML(writer io.Writer, fileName string, headingsNum int) (*Table, error) { +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() - // Parse the html - htmlParser := html.NewTokenizer(file) // file must be a utf-8 encoded html or error + + htmlParser := html.NewTokenizer(file) var isTh bool var isTd bool - var n int // n is the number of th tags in the html file var depth int var headings []string - var records []string + var cellData []string table := NewWriter(writer) - // start a loop tokenizing the html for { tt := htmlParser.Next() switch { case tt == html.ErrorToken: return table, nil - // if the token gets to a start tag that is td or th, make isTd and isTh true case tt == html.StartTagToken: t := htmlParser.Token() isTd = t.Data == "td" @@ -38,18 +35,18 @@ func NewHTML(writer io.Writer, fileName string, headingsNum int) (*Table, error) case tt == html.TextToken: t := htmlParser.Token() if isTd { - records = append(records, t.Data) - depth++ + cellData = append(cellData, t.Data) + depth++ } if isTh { headings = append(headings, t.Data) - n++ + depth++ } - if isTd && depth % headingsNum == 0 { - table.Append(records) - records = nil + if isTd && depth % columnNum == 0 { + table.Append(cellData) + cellData = nil } - if isTh && n % headingsNum == 0 { + if isTh && depth % columnNum == 0 { table.SetHeader(headings) } isTd = false diff --git a/table_test.go b/table_test.go index 75c241a..6471102 100644 --- a/table_test.go +++ b/table_test.go @@ -98,8 +98,8 @@ func ExampleNewCSV() { // *============*===========*=========* } -func ExampleNewHTML() { - table, _ := NewHTML(os.Stdout, "testdata/test.html", 4) +func ExampleNewHTMLWithHeadings() { + table, _ := NewHTML(os.Stdout, "testdata/test1.html", 4) table.SetCenterSeparator("*") table.SetRowSeparator("=") @@ -119,6 +119,48 @@ func ExampleNewHTML() { // *=====*========*=====*================================* } +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 | + // *==========*==========*==========*================================* +} + // TestNumLines to test the numbers of lines func TestNumLines(t *testing.T) { data := [][]string{ diff --git a/testdata/test.html b/testdata/test1.html similarity index 100% rename from testdata/test.html rename to testdata/test1.html 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 From 2e71dead46e1c43b3135cf8f4e82ff2fddbe5f91 Mon Sep 17 00:00:00 2001 From: Nelson Isioma <58360242+Nelwhix@users.noreply.github.com> Date: Fri, 7 Jul 2023 22:45:06 +0100 Subject: [PATCH 6/6] added extra test edge case for newHTML --- table_test.go | 64 ++++++++++++++++++++++++++++++++++++--------- testdata/test4.html | 7 +++++ 2 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 testdata/test4.html diff --git a/table_test.go b/table_test.go index c5e5aa3..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"}, @@ -105,18 +131,18 @@ func ExampleNewHTMLWithHeadings() { 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 | -// *=====*========*=====*================================* + // 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() { @@ -161,6 +187,20 @@ func ExampleNewMalHTML() { // *==========*==========*==========*================================* } +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/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 + +