forked from crufter/banner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
banner.go
136 lines (118 loc) · 2.31 KB
/
banner.go
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
package banner
import (
"fmt"
"strings"
"github.com/hifx/banner/fonts"
)
var joker = `
___
/ _ \
\// /
\/
()
`
var jokerInf letterInfos
var jokerLines []string
func init() {
a, b := processOne(joker)
jokerInf = b
jokerLines = a
}
type letterInfos struct {
lineNum int
maxWidth int
}
type Banner struct {
font map[string][]string
info map[string]letterInfos
}
func trimRight(s string) string {
return strings.TrimRightFunc(s, func(s rune) bool { return s == ' ' })
}
func processOne(s string) ([]string, letterInfos) {
lines := strings.Split(s, "\n")
maxw := 0
for i, line := range lines {
lin := trimRight(line)
if len(lin) > maxw {
maxw = len(lin)
}
lines[i] = lin
}
return lines, letterInfos{
len(lines),
maxw,
}
}
func process(m map[string]string) (map[string][]string, map[string]letterInfos) {
tr := map[string][]string{}
inf := map[string]letterInfos{}
for k, v := range m {
a, b := processOne(v)
tr[k] = a
inf[k] = b
}
return tr, inf
}
func NewBanner(m map[string]string) Banner {
trimmed, infos := process(m)
return Banner{trimmed, infos}
}
func padRight(s string, width int) string {
if len(s) < width {
s += strings.Repeat(" ", width-len(s))
}
return s
}
func (b Banner) getOne(s string) ([]string, letterInfos) {
linf, ok := b.info[s]
if !ok {
joker, okj := b.info["?"]
if okj {
return b.font["?"], joker
}
return jokerLines, jokerInf
}
return b.font[s], linf
}
func (b Banner) print(text string, printOut bool) string {
bannerMaxHeight := 0
// Calculating max height of banner
for _, v := range text {
_, linf := b.getOne(string(v))
if linf.lineNum > bannerMaxHeight {
bannerMaxHeight = linf.lineNum
}
}
ret := ""
// Render
for i := 0; i < bannerMaxHeight-1; i++ {
thisLin := ""
for _, v := range text {
lines, linf := b.getOne(string(v))
if linf.lineNum <= i {
thisLin += padRight("", linf.maxWidth)
} else {
thisLin += padRight(lines[i], linf.maxWidth)
}
}
if printOut {
fmt.Println(thisLin)
} else {
ret += thisLin + "\n"
}
}
return ret
}
func (b Banner) PrintS(text string) string {
return b.print(text, false)
}
func (b Banner) Print(text string) {
b.print(text, true)
}
func Print(s string) {
NewBanner(fonts.Ogre).Print(s)
}
func PrintS(s string) string {
return NewBanner(fonts.Ogre).PrintS(s)
}