183 lines
4.1 KiB
Go
183 lines
4.1 KiB
Go
package pterm
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/mattn/go-runewidth"
|
|
|
|
"github.com/pterm/pterm/internal"
|
|
)
|
|
|
|
// Panel contains the data, which should be printed inside a PanelPrinter.
|
|
type Panel struct {
|
|
Data string
|
|
}
|
|
|
|
// Panels is a two dimensional coordinate system for Panel.
|
|
type Panels [][]Panel
|
|
|
|
// DefaultPanel is the default PanelPrinter.
|
|
var DefaultPanel = PanelPrinter{
|
|
Padding: 1,
|
|
}
|
|
|
|
// PanelPrinter prints content in boxes.
|
|
type PanelPrinter struct {
|
|
Panels Panels
|
|
Padding int
|
|
BottomPadding int
|
|
SameColumnWidth bool
|
|
BoxPrinter BoxPrinter
|
|
}
|
|
|
|
// WithPanels returns a new PanelPrinter with specific options.
|
|
func (p PanelPrinter) WithPanels(panels Panels) *PanelPrinter {
|
|
p.Panels = panels
|
|
return &p
|
|
}
|
|
|
|
// WithPadding returns a new PanelPrinter with specific options.
|
|
func (p PanelPrinter) WithPadding(padding int) *PanelPrinter {
|
|
if padding < 0 {
|
|
padding = 0
|
|
}
|
|
p.Padding = padding
|
|
return &p
|
|
}
|
|
|
|
// WithBottomPadding returns a new PanelPrinter with specific options.
|
|
func (p PanelPrinter) WithBottomPadding(bottomPadding int) *PanelPrinter {
|
|
if bottomPadding < 0 {
|
|
bottomPadding = 0
|
|
}
|
|
p.BottomPadding = bottomPadding
|
|
return &p
|
|
}
|
|
|
|
// WithSameColumnWidth returns a new PanelPrinter with specific options.
|
|
func (p PanelPrinter) WithSameColumnWidth(b ...bool) *PanelPrinter {
|
|
b2 := internal.WithBoolean(b)
|
|
p.SameColumnWidth = b2
|
|
return &p
|
|
}
|
|
|
|
// WithBoxPrinter returns a new PanelPrinter with specific options.
|
|
func (p PanelPrinter) WithBoxPrinter(boxPrinter BoxPrinter) *PanelPrinter {
|
|
p.BoxPrinter = boxPrinter
|
|
return &p
|
|
}
|
|
|
|
func (p PanelPrinter) getRawOutput() string {
|
|
var ret string
|
|
for _, panel := range p.Panels {
|
|
for _, panel2 := range panel {
|
|
ret += panel2.Data + "\n\n"
|
|
}
|
|
ret += "\n"
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// Srender renders the Template as a string.
|
|
func (p PanelPrinter) Srender() (string, error) {
|
|
var ret string
|
|
|
|
if RawOutput {
|
|
return p.getRawOutput(), nil
|
|
}
|
|
|
|
for i := range p.Panels {
|
|
for i2 := range p.Panels[i] {
|
|
p.Panels[i][i2].Data = strings.TrimSuffix(p.Panels[i][i2].Data, "\n")
|
|
}
|
|
}
|
|
|
|
if p.BoxPrinter != (BoxPrinter{}) {
|
|
for i := range p.Panels {
|
|
for i2 := range p.Panels[i] {
|
|
p.Panels[i][i2].Data = p.BoxPrinter.Sprint(p.Panels[i][i2].Data)
|
|
}
|
|
}
|
|
}
|
|
|
|
for i := range p.Panels {
|
|
if len(p.Panels)-1 != i {
|
|
for i2 := range p.Panels[i] {
|
|
p.Panels[i][i2].Data += strings.Repeat("\n", p.BottomPadding)
|
|
}
|
|
}
|
|
}
|
|
|
|
columnMaxHeightMap := make(map[int]int)
|
|
|
|
if p.SameColumnWidth {
|
|
for _, panel := range p.Panels {
|
|
for i, p2 := range panel {
|
|
if columnMaxHeightMap[i] < internal.GetStringMaxWidth(p2.Data) {
|
|
columnMaxHeightMap[i] = internal.GetStringMaxWidth(p2.Data)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, boxLine := range p.Panels {
|
|
var maxHeight int
|
|
|
|
var renderedPanels []string
|
|
|
|
for _, box := range boxLine {
|
|
renderedPanels = append(renderedPanels, box.Data)
|
|
}
|
|
|
|
for i, panel := range renderedPanels {
|
|
renderedPanels[i] = strings.ReplaceAll(panel, "\n", Reset.Sprint()+"\n")
|
|
}
|
|
|
|
for _, box := range renderedPanels {
|
|
height := len(strings.Split(box, "\n"))
|
|
if height > maxHeight {
|
|
maxHeight = height
|
|
}
|
|
}
|
|
|
|
for i := 0; i < maxHeight; i++ {
|
|
if maxHeight != i {
|
|
for j, letter := range renderedPanels {
|
|
var letterLine string
|
|
letterLines := strings.Split(letter, "\n")
|
|
var maxLetterWidth int
|
|
if !p.SameColumnWidth {
|
|
maxLetterWidth = internal.GetStringMaxWidth(letter)
|
|
}
|
|
if len(letterLines) > i {
|
|
letterLine = letterLines[i]
|
|
}
|
|
letterLineLength := runewidth.StringWidth(RemoveColorFromString(letterLine))
|
|
if !p.SameColumnWidth {
|
|
if letterLineLength < maxLetterWidth {
|
|
letterLine += strings.Repeat(" ", maxLetterWidth-letterLineLength)
|
|
}
|
|
} else {
|
|
if letterLineLength < columnMaxHeightMap[j] {
|
|
letterLine += strings.Repeat(" ", columnMaxHeightMap[j]-letterLineLength)
|
|
}
|
|
}
|
|
letterLine += strings.Repeat(" ", p.Padding)
|
|
ret += letterLine
|
|
}
|
|
ret += "\n"
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
// Render prints the Template to the terminal.
|
|
func (p PanelPrinter) Render() error {
|
|
s, _ := p.Srender()
|
|
Println(s)
|
|
|
|
return nil
|
|
}
|