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/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 |
+
+
\ 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
+ |
+ 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 |
+
\ 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 @@
+
+
+ 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 |
+
+
\ 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 |
+
+