Skip to content

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

Closed
@ondrovic

Description

@ondrovic

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions