lolcat_使用Go构建命令行应用程序:lolcat

lolcat

Like CLI apps? Don’t miss the cowsay tutorial as well!

喜欢CLI应用程序吗? 也不要错过Cowsay教程!

I was looking for some terminal applications for inspiration and I stumbled on lolcat.

我一直在寻找一些终端应用程序来寻求灵感,但偶然发现了lolcat

The original is https://github.com/busyloop/lolcat and there are quite a few Go implementations already:

原始版本是https://github.com/busyloop/lolcat,并且已经有很多Go实现:

Looks like a completely useless thing to build, so let’s do it!

看起来好像是一件完全没用的东西 ,让我们开始吧!

Let’s start by printing some values on the screen, then we’ll move to coloring them, and then we’ll look into accepting user input to work as a pipe.

让我们从在屏幕上打印一些值开始,然后为它们着色,然后研究接受用户输入以充当管道。

I use https://github.com/enodata/faker to generate fake output.

我使用https://github.com/enodata/faker生成假输出。

go get -u github.com/enodata/faker

This program outputs a number of phrases:

该程序输出许多短语:

package main

import (
    "fmt"
    "strings"

    "github.com/enodata/faker"
)

func main() {
    var phrases []string

    for i := 1; i < 3; i++ {
        phrases = append(phrases, faker.Hacker().Phrases()...)
    }

    fmt.Println(strings.Join(phrases[:], "; "))
}

Unfortunately, this is all boring B/W. Let’s add some color. We can do this by prepending an escape character sequence in fmt.Printf. This prints all the strings in the gold color #FFD700, whose RGB color code is (255,215,0):

不幸的是,这真是无聊的黑白。 让我们添加一些颜色。 我们可以通过在fmt.Printf添加一个转义字符序列来做到这fmt.Printf 。 这将以金色#FFD700打印所有字符串,其RGB颜色代码为(255,215,0):

package main

import (
    "fmt"
    "strings"

    "github.com/enodata/faker"
)

func main() {
    var phrases []string

    for i := 1; i < 3; i++ {
        phrases = append(phrases, faker.Hacker().Phrases()...)
    }

    output := strings.Join(phrases[:], "; ")
    r, g, b := 255, 215, 0 //gold color

    for j := 0; j < len(output); j++ {
        fmt.Printf("\033[38;2;%d;%d;%dm%c\033[0m", r, g, b, output[j])
    }
}

Now that we have a string, and the groundwork for making each character colored in a different way, it’s time to introduce the rainbow.

既然我们有了一个字符串,并且使每个字符以不同的方式着色的基础工作,该介绍彩虹了。

package main

import (
    "fmt"
    "math"
    "strings"

    "github.com/enodata/faker"
)

func rgb(i int) (int, int, int) {
    var f = 0.1
    return int(math.Sin(f*float64(i)+0)*127 + 128),
        int(math.Sin(f*float64(i)+2*math.Pi/3)*127 + 128),
        int(math.Sin(f*float64(i)+4*math.Pi/3)*127 + 128)
}

func main() {
    var phrases []string

    for i := 1; i < 3; i++ {
        phrases = append(phrases, faker.Hacker().Phrases()...)
    }

    output := strings.Join(phrases[:], "; ")

    for j := 0; j < len(output); j++ {
        r, g, b := rgb(j)
        fmt.Printf("\033[38;2;%d;%d;%dm%c\033[0m", r, g, b, output[j])
    }
    fmt.Println()
}

That’s style!

那是风格!

The rainbow color is generated using the rgb() function, as implemented in the original Ruby source code in https://github.com/busyloop/lolcat/blob/master/lib/lolcat/lol.rb

彩虹色是使用rgb()函数生成的,如在https://github.com/busyloop/lolcat/blob/master/lib/lolcat/lol.rb中的原始Ruby源代码中所实现的那样

Let’s now edit the program and instead of providing its own output, let it work as a pipe for other programs. It will read the content from os.Stdin and rainbowize it.

现在让我们编辑程序,而不是提供自己的输出,而让它充当其他程序的管道 。 它将从os.Stdin读取内容并将其彩虹化。

package main

import (
    "bufio"
    "fmt"
    "io"
    "math"
    "os"
)

func rgb(i int) (int, int, int) {
    var f = 0.1
    return int(math.Sin(f*float64(i)+0)*127 + 128),
        int(math.Sin(f*float64(i)+2*math.Pi/3)*127 + 128),
        int(math.Sin(f*float64(i)+4*math.Pi/3)*127 + 128)
}

func print(output []rune) {
    for j := 0; j < len(output); j++ {
        r, g, b := rgb(j)
        fmt.Printf("\033[38;2;%d;%d;%dm%c\033[0m", r, g, b, output[j])
    }
    fmt.Println()
}

func main() {
    info, _ := os.Stdin.Stat()
    var output []rune

    if info.Mode()&os.ModeCharDevice != 0 {
        fmt.Println("The command is intended to work with pipes.")
        fmt.Println("Usage: fortune | gorainbow")
    }

    reader := bufio.NewReader(os.Stdin)
    for {
        input, _, err := reader.ReadRune()
        if err != nil && err == io.EOF {
            break
        }
        output = append(output, input)
    }

    print(output)
}

It reads one rune at a time from os.Stdin and adds it to the output slice of runes.

它一次从os.Stdin读取一个符文,并将其添加到output符文中。

The output rendering has been extracted to print(), but we could also pipe “just in time” each rune as it’s scanned:

输出渲染已提取到print()中,但是我们也可以在扫描每个符文时“及时”传递它:

package main

import (
    "bufio"
    "fmt"
    "io"
    "math"
    "os"
)

func rgb(i int) (int, int, int) {
    var f = 0.1
    return int(math.Sin(f*float64(i)+0)*127 + 128),
        int(math.Sin(f*float64(i)+2*math.Pi/3)*127 + 128),
        int(math.Sin(f*float64(i)+4*math.Pi/3)*127 + 128)
}

func main() {
    info, _ := os.Stdin.Stat()

    if info.Mode()&os.ModeCharDevice != 0 {
        fmt.Println("The command is intended to work with pipes.")
        fmt.Println("Usage: fortune | gorainbow")
    }

    reader := bufio.NewReader(os.Stdin)
    j := 0
    for {
        input, _, err := reader.ReadRune()
        if err != nil && err == io.EOF {
            break
        }
        r, g, b := rgb(j)
        fmt.Printf("\033[38;2;%d;%d;%dm%c\033[0m", r, g, b, input)
        j++
    }
}

This works same as before.

这和以前一样。

We can now entertain ourselves with fortune and cowsay

我们现在可以用财富和求知欲来娱乐自己

Let’s make this a system-wide command by running go build and go install. The command will be run as gololcat, since we used that as the folder name.

通过运行go buildgo install使它成为系统范围的命令。 该命令将以gololcat运行,因为我们将其用作文件夹名称。

翻译自: https://flaviocopes.com/go-tutorial-lolcat/

lolcat

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值