package main import ( "fmt" "strings" ) const ( boxErrHorLine = '═' boxErrHorDownLine = '╦' boxErrHorUpLine = '╩' boxErrVertLine = '║' boxErrVertRightLine = '╠' boxErrVertLeftLine = '╣' boxErrTopLeftCorner = '╔' boxErrTopRightCorner = '╗' boxErrBottomLeftCorner = '╚' boxErrBottomRightCorner = '╝' boxHorLine = '─' boxHorDownLine = '┬' boxHorUpLine = '┴' boxVertLine = '│' boxVertRightLine = '├' boxVertLeftLine = '┤' boxTopLeftCorner = '┌' boxTopRightCorner = '┐' boxBottomLeftCorner = '└' boxBottomRightCorner = '┘' ) // Returns an error box func errorBox(message string) (box string) { // 2+len because message length doesn't accomodate the spaces between the left and right border box += fmt.Sprintf("%c%v%c\n", boxErrTopLeftCorner, repeatRune(boxErrHorLine, 2+len(message)), boxErrTopRightCorner) box += fmt.Sprintf("%c %v %c\n", boxErrVertLine, message, boxErrVertLine) box += fmt.Sprintf("%c%v%c\n", boxErrBottomLeftCorner, repeatRune(boxErrHorLine, 2+len(message)), boxErrBottomRightCorner) return } // Returns a normal box, most commonly used for the menu items func normalBox(railed bool, messages ...string) (box string) { message := strings.Join(messages, " │ ") var messagesLengths []int for i := 0; i < len(messages)-1; i++ { messagesLengths = append(messagesLengths, len(messages[i])) } /* The message is the middle part between the left and right border, so you have to add 2 for the spaces between it and the borders. Since each "│" character adds 3 to the length (and not 1), get the amount of "│" character from number of messages, double the value and finally subtract (so, "││" is len 6, 2 "│" characters * 2 = 4, 6 - 4 = 2). */ messageLength := 2 + len(message) - 2*(len(messages)-1) box += fmt.Sprintf("%c%v%c\n", boxTopLeftCorner, repeatRune(boxHorLine, messageLength), boxTopRightCorner) box += fmt.Sprintf("%c %v %c\n", boxVertLine, message, boxVertLine) box += fmt.Sprintf("%c%v%c\n", boxBottomLeftCorner, repeatRune(boxHorLine, messageLength), boxBottomRightCorner) indTop := 0 /* messageLength doesn't include the left and right spaces that are in middle part and on each line there are \n characters (hence adding 2 at the end). With this variable, we're practically at index 0 on the third line. */ indBot := 2*(messageLength+2) + 2 if railed { box = replaceAtIndex(box, boxVertRightLine, indBot) } for _, val := range messagesLengths { /* +1 Because message length doesn't include the " " in the beginning +2 because we're now at the index of the last letter, and need to go to the right border index And that in total means we add 3 to length */ indTop += val + 3 indBot += val + 3 // Replaces the border character on the top with one that connects to the middle border: ┌───────────┬───────────┐ box = replaceAtIndex(box, boxHorDownLine, indTop) // Replaces the border character on the bottom with one that connects to the middle broder: └───────────┴───────────┘ box = replaceAtIndex(box, boxHorUpLine, indBot) } return }