Skip to content

Commit

Permalink
Merge pull request #55 from tmck-code/unicode-box-characters
Browse files Browse the repository at this point in the history
Unicode box characters
  • Loading branch information
tmck-code authored Sep 27, 2023
2 parents 42f1e10 + e456c6d commit fc0c63a
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 29 deletions.
11 changes: 7 additions & 4 deletions pokesay.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,18 @@ func parseFlags() pokesay.Args {
listCategories := flag.Bool("list-categories", false, "list all available categories")
listNames := flag.Bool("list-names", false, "list all available names")
japaneseName := flag.Bool("japanese-name", false, "print the japanese name")
unicodeBox := flag.Bool("unicode-box", false, "use unicode characters to draw the speech box")

flag.Parse()
var args pokesay.Args

if *fastest {
args = pokesay.Args{
Width: *width,
NoWrap: true,
TabSpaces: " ",
NoTabSpaces: true,
Width: *width,
NoWrap: true,
TabSpaces: " ",
NoTabSpaces: true,
BoxCharacters: pokesay.DetermineBoxCharacters(false),
}
} else {
args = pokesay.Args{
Expand All @@ -66,6 +68,7 @@ func parseFlags() pokesay.Args {
Category: *category,
NameToken: *name,
JapaneseName: *japaneseName,
BoxCharacters: pokesay.DetermineBoxCharacters(*unicodeBox),
}
}
return args
Expand Down
100 changes: 75 additions & 25 deletions src/pokesay/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ import (
"github.com/tmck-code/pokesay/src/pokedex"
)

var (
textStyleItalic *color.Color = color.New(color.Italic)
textStyleBold *color.Color = color.New(color.Bold)
)
type BoxCharacters struct {
HorizontalEdge string
VerticalEdge string
TopRightCorner string
TopLeftCorner string
BottomRightCorner string
BottomLeftCorner string
BalloonString string
Separator string
RightArrow string
CategorySeparator string
}

type Args struct {
Width int
Expand All @@ -28,6 +36,44 @@ type Args struct {
Category string
NameToken string
JapaneseName bool
BoxCharacters *BoxCharacters
}

var (
textStyleItalic *color.Color = color.New(color.Italic)
textStyleBold *color.Color = color.New(color.Bold)
AsciiBoxCharacters *BoxCharacters = &BoxCharacters{
HorizontalEdge: "-",
VerticalEdge: "|",
TopRightCorner: "\\",
TopLeftCorner: "/",
BottomRightCorner: "/",
BottomLeftCorner: "\\",
BalloonString: "\\",
Separator: "|",
RightArrow: ">",
CategorySeparator: "/",
}
UnicodeBoxCharacters *BoxCharacters = &BoxCharacters{
HorizontalEdge: "─",
VerticalEdge: "│",
TopRightCorner: "╮",
TopLeftCorner: "╭",
BottomRightCorner: "╯",
BottomLeftCorner: "╰",
BalloonString: "╲",
Separator: "│",
RightArrow: "→ ",
CategorySeparator: "/",
}
)

func DetermineBoxCharacters(unicodeBox bool) *BoxCharacters {
if unicodeBox {
return UnicodeBoxCharacters
} else {
return AsciiBoxCharacters
}
}

// The main print function! This uses a chosen pokemon's index, names and categories, and an
Expand All @@ -36,14 +82,14 @@ type Args struct {
// 2. The cowfile data is retrieved using the matching index, decompressed (un-gzipped),
// 3. The pokemon is printed along with the name & category information
func Print(args Args, choice int, names []string, categories []string, cows embed.FS) {
printSpeechBubble(bufio.NewScanner(os.Stdin), args.Width, args.NoTabSpaces, args.TabSpaces, args.NoWrap)
printSpeechBubble(args.BoxCharacters, bufio.NewScanner(os.Stdin), args.Width, args.NoTabSpaces, args.TabSpaces, args.NoWrap)
printPokemon(args, choice, names, categories, cows)
}

// Prints text from STDIN, surrounded by a speech bubble.
func printSpeechBubble(scanner *bufio.Scanner, width int, noTabSpaces bool, tabSpaces string, noWrap bool) {
border := strings.Repeat("-", width+2)
fmt.Println("/" + border + "\\")
func printSpeechBubble(boxCharacters *BoxCharacters, scanner *bufio.Scanner, width int, noTabSpaces bool, tabSpaces string, noWrap bool) {
border := strings.Repeat(boxCharacters.HorizontalEdge, width+2)
fmt.Println(boxCharacters.TopLeftCorner + border + boxCharacters.TopRightCorner)

for scanner.Scan() {
line := scanner.Text()
Expand All @@ -52,39 +98,41 @@ func printSpeechBubble(scanner *bufio.Scanner, width int, noTabSpaces bool, tabS
line = strings.Replace(line, "\t", tabSpaces, -1)
}
if noWrap {
printSpeechBubbleLine(line, width)
printSpeechBubbleLine(boxCharacters, line, width)
} else {
printWrappedText(line, width, tabSpaces)
printWrappedText(boxCharacters, line, width, tabSpaces)
}
}
fmt.Println("\\" + border + "/")
fmt.Println(boxCharacters.BottomLeftCorner + border + boxCharacters.BottomRightCorner)
for i := 0; i < 4; i++ {
fmt.Println(strings.Repeat(" ", i+8), "\\")
fmt.Println(strings.Repeat(" ", i+8), boxCharacters.BalloonString)
}
}

// Prints a single speech bubble line
func printSpeechBubbleLine(line string, width int) {
func printSpeechBubbleLine(boxCharacters *BoxCharacters, line string, width int) {
if len(line) > width {
fmt.Printf("| %s\n", line)
fmt.Printf("%s %s\n", boxCharacters.VerticalEdge, line)
} else if len(line) == width {
fmt.Printf("| %s |\n", line)
fmt.Printf("%s %s %s\n", boxCharacters.VerticalEdge, line, boxCharacters.VerticalEdge)
} else {
fmt.Printf("| %s%s |\n", line, strings.Repeat(" ", width-len(line)))
fmt.Printf(
"%s %s%s %s\n",
boxCharacters.VerticalEdge, line, strings.Repeat(" ", width-len(line)), boxCharacters.VerticalEdge,
)
}
}

// Prints line of text across multiple lines, wrapping it so that it doesn't exceed the desired width.
func printWrappedText(line string, width int, tabSpaces string) {
func printWrappedText(boxCharacters *BoxCharacters, line string, width int, tabSpaces string) {
for _, wline := range strings.Split(wordwrap.WrapString(strings.Replace(line, "\t", tabSpaces, -1), uint(width)), "\n") {
printSpeechBubbleLine(wline, width)
printSpeechBubbleLine(boxCharacters, wline, width)
}
}

// Prints a pokemon with its name & category information.
func printPokemon(args Args, index int, names []string, categoryKeys []string, GOBCowData embed.FS) {
d, _ := GOBCowData.ReadFile(pokedex.EntryFpath("build/assets/cows", index))
delimiter := "|"

namesFmt := make([]string, 0)
for _, name := range names {
Expand All @@ -93,17 +141,19 @@ func printPokemon(args Args, index int, names []string, categoryKeys []string, G

if args.NoCategoryInfo {
fmt.Printf(
"%s> %s\n",
"%s%s %s\n",
pokedex.Decompress(d),
strings.Join(namesFmt, fmt.Sprintf(" %s ", delimiter)),
args.BoxCharacters.RightArrow,
strings.Join(namesFmt, fmt.Sprintf(" %s ", args.BoxCharacters.Separator)),
)
} else {
fmt.Printf(
"%s> %s %s %s\n",
"%s%s %s %s %s\n",
pokedex.Decompress(d),
strings.Join(namesFmt, fmt.Sprintf(" %s ", delimiter)),
delimiter,
textStyleItalic.Sprint(strings.Join(categoryKeys, "/")),
args.BoxCharacters.RightArrow,
strings.Join(namesFmt, fmt.Sprintf(" %s ", args.BoxCharacters.Separator)),
args.BoxCharacters.Separator,
textStyleItalic.Sprint(strings.Join(categoryKeys, args.BoxCharacters.CategorySeparator)),
)
}
}

0 comments on commit fc0c63a

Please sign in to comment.