-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
145 lines (122 loc) · 3.9 KB
/
Copy pathmain.go
File metadata and controls
145 lines (122 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
"unicode/utf8"
)
// ! buildBalloons takes in a slice of strings (lines) and an integer (maxWidth)
// ! and returns a string representing a balloon with the lines inside, bordered with characters
func buildBalloons(lines []string, maxWidth int) string {
//* Define the possible borders for the balloon
borders := []string{"/", "\\", "\\", "/", "|", "<", ">"}
//* Get the count of lines
count := len(lines)
//* Create a slice to hold the balloon's lines
var returnValue []string
//* Top border of the balloon, which is a string of underscores with extra space for padding
top := " " + strings.Repeat("_", maxWidth+2)
//* Bottom border of the balloon, which is a string of hyphens with extra space for padding
bottom := " " + strings.Repeat("-", maxWidth+2)
//* Append the top border to the returnValue slice
returnValue = append(returnValue, top)
//* Check if there is only one line inside the balloon
if count == 1 {
//* For one line, use the '<' and '>' borders to create the shape of the balloon
s := fmt.Sprintf("%s %s %s", borders[5], lines[0], borders[6])
returnValue = append(returnValue, s)
} else {
//? If there are multiple lines, handle the top and bottom lines with different borders
//? For the first line, use '/' and '\\' for the borders
s := fmt.Sprintf("%s %s %s", borders[0], lines[0], borders[1])
returnValue = append(returnValue, s)
//? For the middle lines, use '|' for the left and right borders
for i := 1; i < count-1; i++ {
s = fmt.Sprintf("%s %s %s", borders[4], lines[i], borders[4])
returnValue = append(returnValue, s)
}
//? For the last line, use '\\' and '/' for the borders again
if count > 1 {
s := fmt.Sprintf("%s %s %s", borders[2], lines[count-1], borders[3])
returnValue = append(returnValue, s)
}
}
//* Append the bottom border to the returnValue slice
returnValue = append(returnValue, bottom)
//* Join all the lines in returnValue with newline characters and return the result
return strings.Join(returnValue, "\n")
}
func tabsToSpaces(lines []string) []string {
var returnedValue []string
for _, l := range lines {
l = strings.ReplaceAll(l, "\t", " ") // Using 4 spaces instead of 2 for better visibility
returnedValue = append(returnedValue, l)
}
return returnedValue
}
func calculateMaxWidth(lines []string) int {
width := 0
for _, l := range lines {
length := utf8.RuneCountInString(l)
if length > width {
width = length
}
}
return width
}
func normalizeStringsLength(lines []string, maxwidth int) []string {
var returnValues []string
for _, l := range lines {
currentWidth := utf8.RuneCountInString(l)
s := l + strings.Repeat(" ", maxwidth-currentWidth)
returnValues = append(returnValues, s)
}
return returnValues
}
func main() {
info, err := os.Stdin.Stat()
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading stdin: %v\n", err)
os.Exit(1)
}
if info.Mode()&os.ModeCharDevice != 0 {
fmt.Println("The command is intended to work with pipes.")
fmt.Println("Usage: fortune | gocowsay")
os.Exit(1)
}
var lines []string
reader := bufio.NewReader(os.Stdin)
for {
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
break
}
fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err)
os.Exit(1)
}
lines = append(lines, strings.TrimSpace(line))
}
// Remove empty last line if it exists
if len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
// Check if we have any input
if len(lines) == 0 {
fmt.Println("No input received")
os.Exit(1)
}
cow := ` \ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||`
lines = tabsToSpaces(lines)
maxWidth := calculateMaxWidth(lines)
message := normalizeStringsLength(lines, maxWidth)
balloons := buildBalloons(message, maxWidth)
fmt.Println(balloons)
fmt.Println(cow)
}