Skip to content
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

[Bug] text.Hyperlink breaks table alignment of header, footer and row data #329

Closed
ondrovic opened this issue Aug 30, 2024 · 5 comments · Fixed by #334
Closed

[Bug] text.Hyperlink breaks table alignment of header, footer and row data #329

ondrovic opened this issue Aug 30, 2024 · 5 comments · Fixed by #334
Labels
bug Something isn't working

Comments

@ondrovic
Copy link

Describe the bug
When using text.Hyperlink() inside of table, the alignment between the header, footer and data rows is off

To Reproduce

Expand Code
package main

import (
    "fmt"
    "math"
    "os"

    "github.com/jedib0t/go-pretty/v6/table"
    "github.com/jedib0t/go-pretty/v6/text"
)

type SizeUnit struct {
    Label string
    Size  int64
}

var (
    SizeUnits = []SizeUnit{
        {Label: "PB", Size: 1 << 50}, // Petabyte
        {Label: "TB", Size: 1 << 40}, // Terabyte
        {Label: "GB", Size: 1 << 30}, // Gigabyte
        {Label: "MB", Size: 1 << 20}, // Megabyte
        {Label: "KB", Size: 1 << 10}, // Kilobyte
        {Label: "B", Size: 1},        // Byte
    }

    tableHeader = table.Row{
        "Directory", "FileName", "FileSize",
    }

    testRows = []table.Row{
        {"C:\\Temp", "Test.txt", "60 KB"},
        {"C:\\Temp", "Some Long Test Name.txt", "120 B"},
        {"C:\\Temp\\Sub\\Another", "Test.mp4", "3.15 MB"},
        {"C:\\Temp\\Sub\\Sub\\Another", "Something Longer", "15 B"},
    }

    totalCount int   = len(testRows)
    totalSize  int64 = 3366071 // 3.21

    tableFooter = table.Row{
        "Total", totalCount, formatSize(totalSize),
    }
)

func formatSize(bytes int64) string {
    for _, unit := range SizeUnits {
        if bytes >= unit.Size {
            value := float64(bytes) / float64(unit.Size)
            // Round the value to two decimal places
            roundedValue := math.Round(value*100) / 100
            return fmt.Sprintf("%.2f %s", roundedValue, unit.Label)
        }
    }

    return "0 B"
}

func main() {
    renderNormalTable()
    fmt.Println("")
    renderTableWithHyperlinks()
}

// table is formatted like it should be, header, footer, and row data line up like they should, no matter the size
func renderNormalTable() {
    //  new table
    t := table.Table{}

    // create header
    t.AppendHeader(tableHeader)

    // create data
    t.AppendRows(testRows)

    // create the footer
    t.AppendFooter(tableFooter)

    t.SetStyle(table.StyleColoredDark)
    t.SetOutputMirror(os.Stdout)
    t.Render()
}

// table formatting is broken, header, footer and row data are off
func renderTableWithHyperlinks() {
    //  new table
    t := table.Table{}

    // create header
    t.AppendHeader(tableHeader)

    // create data
    for _, row := range testRows {
        dir := fmt.Sprintf("%v", row[0])
        file := fmt.Sprintf("%v", row[1])
        size := fmt.Sprintf("%v", row[2])

        t.AppendRow(table.Row{
            text.Hyperlink(dir, dir),
            text.Hyperlink(file, file),
            size,
        })
    }

    // create the footer
    t.AppendFooter(tableFooter)

    t.SetStyle(table.StyleColoredDark)
    t.SetOutputMirror(os.Stdout)
    t.Render()
}

Expected behavior
The header, footers should be aligned with the row data

Screenshots
Based on the above example code
image

Software (please complete the following information):

  • OS: Windows 11
  • GoLang Version: go1.23.0 windows/amd64

Additional context
Add any other context about the problem here.

@jedib0t jedib0t added the bug Something isn't working label Sep 1, 2024
@jedib0t
Copy link
Owner

jedib0t commented Sep 1, 2024

Thanks for the detailed report. Will look into it.

@ondrovic
Copy link
Author

ondrovic commented Sep 1, 2024

Thanks for the detailed report. Will look into it.

This very well could be related to this

@jedib0t
Copy link
Owner

jedib0t commented Oct 3, 2024

Found the bug. The text.Hyperlink code used OSI Escape Codes, which resulted in the \\ in the directory name clashing with the escape codes in the logic that calculated the length of the text. Will try to fix this in the right way soon. If you flip the \\ in the directories to /, you won't have this bug.

@jedib0t
Copy link
Owner

jedib0t commented Oct 3, 2024

The fix is part of tag v6.6.0 @ https://github.com/jedib0t/go-pretty/releases/tag/v6.6.0 - please let me know if you face any issues with this release.

@ondrovic
Copy link
Author

ondrovic commented Oct 3, 2024

Thanks just tested seems to be working as expected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants