-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
There is an issue with calculating the length of line breaks in wrap func #344
Comments
This is probably related to the fact that the non-english (wide) characters are messing with the alignment. I'll see if I can fix this, but this may be an impossible one. |
hi jedib0t, i found this module: https://pkg.go.dev/github.com/mattn/go-runewidth. it seems that this module can roughly calculate the character display width, like: package main
import (
"fmt"
"github.com/mattn/go-runewidth"
)
func main() {
test_data := []string{
"这是一个测试",
"aaaaaaaaaa",
"つのだ☆HIRO",
"aaaaaaaaaa",
}
for _, text := range test_data {
fmt.Printf("| text: %s | width: %d\n", text, runewidth.StringWidth(text))
}
} output:
although there are still not perfect, can we implement runewith restrictions within the cells, like: package main
import (
"fmt"
"github.com/mattn/go-runewidth"
)
func main() {
data := []string{
"abcd甲乙丙丁abcd",
"abcdabcdabcdabcdabcdabcd",
"甲乙丙丁甲乙丙丁甲乙丙丁",
}
fmt.Println("==== ==== ")
max_width := 12
for _, text := range data {
output_str := ""
str_len := 0
for _, ch := range text {
if str_len+runewidth.RuneWidth(ch) > max_width {
break
}
str_len = str_len + runewidth.RuneWidth(ch)
output_str += string(ch)
}
fmt.Printf("| width: %d| text: %s | \n", runewidth.StringWidth(output_str), output_str)
}
fmt.Println("==== ==== ")
} in windows terminal, it looks like: Ubuntu default Shell: Mac iTerm: goland: |
go-pretty uses that library already to calculate the width. |
Can you try the second block of code I shared? The one that says "your code refactored", and share the output? // your code (refactored with SetColumnConfigs)
t = table.NewWriter()
t.AppendHeader(table.Row{"idx", "A", "B", "C"})
t.AppendRows([]table.Row{
{1, "abcd甲乙丙丁abcd", "abcd甲乙丙丁abcd", "abcd甲乙丙丁abcd"},
{2, "abcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcd"},
{3, "甲乙丙丁甲乙丙丁甲乙丙丁", "甲乙丙丁甲乙丙丁甲乙丙丁", "甲乙丙丁"},
})
t.SetColumnConfigs([]table.ColumnConfig{
{Name: "A", WidthMax: 10, WidthMaxEnforcer: text.WrapSoft},
{Name: "B", WidthMax: 10, WidthMaxEnforcer: text.WrapHard},
{Name: "C", WidthMax: 10, WidthMaxEnforcer: text.WrapText},
})
t.SetOutputMirror(os.Stdout)
t.SetStyle(table.StyleLight)
t.SetTitle("Your Code Refactored")
t.Render() |
sure: |
do you mean the WidthMax?
but it looks like widthMax limits the word length not the width, i believe something must be wrong. |
No all alignment and width calculations done under the hood uses that library. Share your terminal settings esp your LANG environment variable. |
I use the go-runewidth package impl the WrapRuneWidth func, then it looks like: package main
import (
"os"
"strings"
"github.com/jedib0t/go-pretty/text"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/mattn/go-runewidth"
)
func WrapRuneWidth(str string, wrapWidth int) string {
if wrapWidth <= 0 {
return ""
}
str = strings.Replace(str, "\t", " ", -1)
sLen := runewidth.StringWidth(str)
if sLen <= wrapWidth {
return str
}
output_str := ""
current_line_width := 0
for _, rune := range str {
rune_width := runewidth.RuneWidth(rune)
if current_line_width+rune_width <= wrapWidth {
current_line_width = current_line_width + rune_width
output_str += string(rune)
} else {
current_line_width = rune_width
output_str += "\n" + string(rune)
}
}
return output_str
}
func main() {
// your code (refactored with SetColumnConfigs)
t := table.NewWriter()
t.AppendHeader(table.Row{"idx", "A", "B", "C"})
t.AppendRows([]table.Row{
{1, "abcd甲乙丙丁abcd", "abcd甲乙丙丁abcd", "abcd甲乙丙丁abcd"},
{2, "abcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcd"},
{3, "甲乙丙丁甲乙丙丁甲乙丙丁", "甲乙丙丁甲乙丙丁甲乙丙丁", "甲乙丙丁"},
})
t.SetColumnConfigs([]table.ColumnConfig{
{Name: "A", WidthMax: 10, WidthMaxEnforcer: text.WrapSoft},
{Name: "B", WidthMax: 10, WidthMaxEnforcer: text.WrapHard},
{Name: "C", WidthMax: 10, WidthMaxEnforcer: text.WrapText},
})
t.SetOutputMirror(os.Stdout)
t.SetStyle(table.StyleLight)
t.SetTitle("Your Code Refactored")
t.Render()
t = table.NewWriter()
t.AppendHeader(table.Row{"idx", "A", "B", "C"})
t.AppendRows([]table.Row{
{1, "abcd甲乙丙丁abcd", "abcd甲乙丙丁abcd", "abcd甲乙丙丁abcd"},
{2, "abcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcd"},
{3, "甲乙丙丁甲乙丙丁甲乙丙丁", "甲乙丙丁甲乙丙丁甲乙丙丁", "甲乙丙丁"},
})
t.SetColumnConfigs([]table.ColumnConfig{
{Name: "A", WidthMax: 10, WidthMaxEnforcer: WrapRuneWidth},
{Name: "B", WidthMax: 10, WidthMaxEnforcer: WrapRuneWidth},
{Name: "C", WidthMax: 10, WidthMaxEnforcer: WrapRuneWidth},
})
t.SetOutputMirror(os.Stdout)
t.SetStyle(table.StyleLight)
t.SetTitle("Wrap with WrapRuneWidth")
t.Render()
} output: |
Good catch. Alignment function uses that library. None of the Wrap functions do (I assumed I'd already changed it). Will fix. |
Tag with the fix: https://github.com/jedib0t/go-pretty/releases/tag/v6.6.5 |
Describe the bug
code:
render:
There is clearly still space in columns A and B of the first and second rows, but it has wrapped
Expected behavior
in columns A and B of the first and second rows should not be wrapped. like:
Software (please complete the following information):
The text was updated successfully, but these errors were encountered: