diff --git a/html2text.go b/html2text.go
index 4398909..0c543c6 100644
--- a/html2text.go
+++ b/html2text.go
@@ -2,7 +2,9 @@ package html2text
import (
"bytes"
+ "fmt"
"io"
+ "math"
"regexp"
"strings"
"unicode"
@@ -26,6 +28,7 @@ type PrettyTablesOptions struct {
AutoWrapText bool
ReflowDuringAutoWrap bool
ColWidth int
+ MinColWidth int
ColumnSeparator string
RowSeparator string
CenterSeparator string
@@ -33,6 +36,7 @@ type PrettyTablesOptions struct {
FooterAlignment int
Alignment int
ColumnAlignment []int
+ NoWhiteSapce bool
NewLine string
HeaderLine bool
RowLine bool
@@ -54,6 +58,7 @@ func NewPrettyTablesOptions() *PrettyTablesOptions {
FooterAlignment: tablewriter.ALIGN_DEFAULT,
Alignment: tablewriter.ALIGN_DEFAULT,
ColumnAlignment: []int{},
+ NoWhiteSapce: false,
NewLine: tablewriter.NEWLINE,
HeaderLine: true,
RowLine: false,
@@ -338,6 +343,7 @@ func (ctx *textifyTraverseContext) handleTableElement(node *html.Node) error {
table.SetRowLine(options.RowLine)
table.SetAutoMergeCells(options.AutoMergeCells)
table.SetBorders(options.Borders)
+ table.SetNoWhiteSpace(options.NoWhiteSapce)
}
table.SetHeader(ctx.tableCtx.header)
table.SetFooter(ctx.tableCtx.footer)
@@ -507,11 +513,43 @@ func (ctx *textifyTraverseContext) normalizeHrefLink(link string) string {
// textuual representaitons separated by a single newline.
func (ctx *textifyTraverseContext) renderEachChild(node *html.Node) (string, error) {
buf := &bytes.Buffer{}
+
+ l := ctx.options.PrettyTablesOptions.MinColWidth
+
for c := node.FirstChild; c != nil; c = c.NextSibling {
s, err := FromHTMLNode(c, ctx.options)
if err != nil {
return "", err
}
+
+ // See if a minimum width has been specified and pad as necessary.
+ if l > 0 && len(s) < l {
+ c := 0
+ // Check alignment and pad appropriately.
+ switch ctx.options.PrettyTablesOptions.Alignment {
+ case tablewriter.ALIGN_LEFT:
+ c = l - len(s)
+ spc := strings.Repeat(" ", c)
+ s = fmt.Sprintf("%s%s", s, spc)
+ case tablewriter.ALIGN_RIGHT:
+ c = l - len(s)
+ spc := strings.Repeat(" ", c)
+ s = fmt.Sprintf("%s%s", spc, s)
+ case tablewriter.ALIGN_CENTER:
+ ls := len(s)
+ c := 0.0 // We need to use a float to have the division work properly here, so declare a local scope variable named c rather than use the int version of c from the parent.
+ c = math.Floor(float64(l-ls) / 2.0)
+ spc := strings.Repeat(" ", int(c))
+ s = fmt.Sprintf("%s%s", spc, s)
+ c = math.Ceil(float64(l-ls) / 2.0)
+ spc = strings.Repeat(" ", int(c))
+ s = fmt.Sprintf("%s%s", s, spc)
+ case tablewriter.ALIGN_DEFAULT: // Default to left alignment.
+ c = l - len(s)
+ spc := strings.Repeat(" ", c)
+ s = fmt.Sprintf("%s%s", s, spc)
+ }
+ }
if _, err = buf.WriteString(s); err != nil {
return "", err
}
@@ -524,6 +562,22 @@ func (ctx *textifyTraverseContext) renderEachChild(node *html.Node) (string, err
return buf.String(), nil
}
+// largestChildWidth - Returns the width (in characters) of the largest child of a node.
+func (ctx *textifyTraverseContext) largestChildWidth(node *html.Node) (int, error) {
+ l := 0
+ for c := node.FirstChild; c != nil; c = c.NextSibling {
+ s, err := FromHTMLNode(c, ctx.options)
+ if err != nil {
+ return l, err
+ }
+
+ if len(s) > l {
+ l = len(s)
+ }
+ }
+ return l, nil
+}
+
func getAttrVal(node *html.Node, attrName string) string {
for _, attr := range node.Attr {
if attr.Key == attrName {
diff --git a/html2text_test.go b/html2text_test.go
index 452b45e..e04fc2a 100644
--- a/html2text_test.go
+++ b/html2text_test.go
@@ -9,6 +9,8 @@ import (
"regexp"
"strings"
"testing"
+
+ "github.com/olekukonko/tablewriter"
)
const destPath = "testdata"
@@ -337,6 +339,79 @@ Table 2 Header 1 Table 2 Header 2 Table 2 Footer 1 Table 2 Footer 2 Table 2 Row
PrettyTables: true,
PrettyTablesOptions: NewPrettyTablesOptions(),
}
+
+ // Check pretty tabular ASCII version.
+ if msg, err := wantString(testCase.input, testCase.tabularOutput, options); err != nil {
+ t.Error(err)
+ } else if len(msg) > 0 {
+ t.Log(msg)
+ }
+
+ // Check plain version.
+ if msg, err := wantString(testCase.input, testCase.plaintextOutput); err != nil {
+ t.Error(err)
+ } else if len(msg) > 0 {
+ t.Log(msg)
+ }
+ }
+}
+
+func TestMinColWidthTable(t *testing.T) {
+ testCases := []struct {
+ input string
+ tabularOutput string
+ plaintextOutput string
+ alignment string
+ }{
+ {
+ "
",
+ // Empty table
+ // +--+--+
+ // | | |
+ // +--+--+
+ "+------------+------------+\n| Hello | World! |\n+------------+------------+",
+ "Hello World!",
+ "Left",
+ },
+ {
+ "",
+ // Empty table
+ // +--+--+
+ // | | |
+ // +--+--+
+ "+------------+------------+\n| Hello | World! |\n+------------+------------+",
+ "Hello World!",
+ "Right",
+ },
+ {
+ "",
+ // Empty table
+ // +--+--+
+ // | | |
+ // +--+--+
+ "+------------+------------+\n| Hello | World! |\n+------------+------------+",
+ "Hello World!",
+ "Center",
+ },
+ }
+
+ for _, testCase := range testCases {
+ options := Options{
+ PrettyTables: true,
+ PrettyTablesOptions: NewPrettyTablesOptions(),
+ }
+ options.PrettyTablesOptions.MinColWidth = 10
+
+ switch testCase.alignment {
+ case "Left":
+ options.PrettyTablesOptions.Alignment = tablewriter.ALIGN_LEFT
+ case "Right":
+ options.PrettyTablesOptions.Alignment = tablewriter.ALIGN_RIGHT
+ case "Center":
+ options.PrettyTablesOptions.Alignment = tablewriter.ALIGN_CENTER
+ default:
+ options.PrettyTablesOptions.Alignment = tablewriter.ALIGN_DEFAULT
+ }
// Check pretty tabular ASCII version.
if msg, err := wantString(testCase.input, testCase.tabularOutput, options); err != nil {
t.Error(err)
@@ -351,6 +426,7 @@ Table 2 Header 1 Table 2 Header 2 Table 2 Footer 1 Table 2 Footer 2 Table 2 Row
t.Log(msg)
}
}
+
}
func TestStrippingLists(t *testing.T) {