Skip to content

Commit

Permalink
feat!(border): left/right borders may now be set without top/bottom
Browse files Browse the repository at this point in the history
If the top and bottom borders are missing the left and right borders
will now render. If the text value rendered is one line, this will
essentially work akin to inline mode.
  • Loading branch information
meowgorithm committed Sep 3, 2024
1 parent 1688b74 commit 28ede9f
Showing 1 changed file with 66 additions and 21 deletions.
87 changes: 66 additions & 21 deletions borders.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ import (
// Border contains a series of values which comprise the various parts of a
// border.
type Border struct {
Top string
Bottom string
Left string
Right string
TopLeft string
TopRight string
BottomLeft string
BottomRight string
// Values for all borders.
Top string
Bottom string
Left string
Right string
TopLeft string
TopRight string
BottomLeft string
BottomRight string

// Values for table borders.
MiddleLeft string
MiddleRight string
Middle string
Expand Down Expand Up @@ -235,17 +238,26 @@ func (s Style) applyBorder(str string) string {

border = s.getBorderStyle()

hasBorderTopLeft = border.TopLeft != ""
hasBorderTop = border.Top != ""
hasBorderTopRight = border.TopRight != ""
hasBorderRight = border.Right != ""
hasBorderBottomRight = border.BottomRight != ""
hasBorderBottom = border.Bottom != ""
hasBorderBottomLeft = border.BottomLeft != ""
hasBorderLeft = border.Left != ""

// Determine if a border was set. Borders also contain a middle section
// for tables, but those don't apply here, so we explicitly check for
// the relevant parts of borders only.
hasBorder = border.Top != "" ||
border.Bottom != "" ||
border.Left != "" ||
border.Right != "" ||
border.TopLeft != "" ||
border.TopRight != "" ||
border.BottomLeft != "" ||
border.BottomRight != ""
hasBorder = hasBorderTop ||
hasBorderBottom ||
hasBorderLeft ||
hasBorderRight ||
hasBorderTopLeft ||
hasBorderTopRight ||
hasBorderBottomLeft ||
hasBorderBottomRight

hasTop = s.getAsBool(borderTopKey, false)
hasRight = s.getAsBool(borderRightKey, false)
Expand Down Expand Up @@ -277,6 +289,39 @@ func (s Style) applyBorder(str string) string {
return str
}

// But should we really render the top border?
if !topSet && !hasBorderTop && !hasBorderTopLeft && !hasBorderTopRight {
hasTop = false
}

// And should we render the bottom border?
if !bottomSet && !hasBorderBottom && !hasBorderBottomLeft && !hasBorderBottomRight {
hasBottom = false
}

// Don't render horizontal borders if the top and bottom won't be rendered
// and the border edge isn't set.
//
// For example, we wouldn't render a left border in the following case
// because setting the right border only nullifies other borders:
//
// Style().
// BorderStyle(NormalBorder()).
// BorderRight(true)
//
// We also wouldn't render the left border in the following case, where the
// top and bottom borders are missing and the left border doesn't have
// a value set:
//
// Style().
// BorderStyle(Border{Right: "│"})
if !hasBorderLeft && !hasTop && !hasBottom {
hasLeft = false
}
if !hasBorderRight && !hasTop && !hasBottom {
hasRight = false
}

lines, width := getLines(str)

if hasLeft {
Expand All @@ -290,8 +335,8 @@ func (s Style) applyBorder(str string) string {
border.Right = " "
}

// If corners should be rendered but are set with the empty string, fill them
// with a single space.
// If corners should be rendered but are set with the empty string, fill
// them with a single space.
if hasTop && hasLeft && border.TopLeft == "" {
border.TopLeft = " "
}
Expand Down Expand Up @@ -338,7 +383,7 @@ func (s Style) applyBorder(str string) string {

var out strings.Builder

// Render top
// Render top. This includes the top left and right corners.
if hasTop {
top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
top = s.styleBorder(top, topFG, topBG)
Expand All @@ -352,7 +397,7 @@ func (s Style) applyBorder(str string) string {
rightRunes := []rune(border.Right)
rightIndex := 0

// Render sides
// Render sides. This never includes any corners.
for i, l := range lines {
if hasLeft {
r := string(leftRunes[leftIndex])
Expand All @@ -376,7 +421,7 @@ func (s Style) applyBorder(str string) string {
}
}

// Render bottom
// Render bottom. This includes the bottom left and right corners.
if hasBottom {
bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width)
bottom = s.styleBorder(bottom, bottomFG, bottomBG)
Expand Down

0 comments on commit 28ede9f

Please sign in to comment.