Создайте приложение командной строки с помощью Go: lolcat

Нравится приложениям с интерфейсом командной строки?Не пропуститекоровье высказываниетакже учебник!

Искал какие-то терминальные приложения для вдохновения и наткнулся налолкот.

Оригиналhttps://github.com/busyloop/lolcatи уже существует довольно много реализаций Go:

Выглядит каксовершенно бесполезная вещьпостроить, так что давайте!

Начнем с печати некоторых значений на экране, затем перейдем к их раскрашиванию, а затем рассмотрим возможность принятия пользовательского ввода для работы в качестве канала.

я используюhttps://github.com/enodata/fakerдля создания поддельного вывода.

go get -u github.com/enodata/faker

Эта программа выводит ряд фраз:

package main

import ( “fmt” “strings”

<span style="color:#e6db74">"github.com/enodata/faker"</span>

)

func main() { var phrases []string

<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span>; <span style="color:#a6e22e">i</span> &lt; <span style="color:#ae81ff">3</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> {
    <span style="color:#a6e22e">phrases</span> = append(<span style="color:#a6e22e">phrases</span>, <span style="color:#a6e22e">faker</span>.<span style="color:#a6e22e">Hacker</span>().<span style="color:#a6e22e">Phrases</span>()<span style="color:#f92672">...</span>)
}

<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Join</span>(<span style="color:#a6e22e">phrases</span>[:], <span style="color:#e6db74">"; "</span>))

}

К сожалению, это все скучно ч / б. Добавим немного цвета. Мы можем сделать это, добавив последовательность escape-символов вfmt.Printf. Это напечатает все струны золотым цветом # FFD700, чьиЦветовой код RGBэто (255,215,0):

package main

import ( “fmt” “strings”

<span style="color:#e6db74">"github.com/enodata/faker"</span>

)

func main() { var phrases []string

<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span>; <span style="color:#a6e22e">i</span> &lt; <span style="color:#ae81ff">3</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> {
    <span style="color:#a6e22e">phrases</span> = append(<span style="color:#a6e22e">phrases</span>, <span style="color:#a6e22e">faker</span>.<span style="color:#a6e22e">Hacker</span>().<span style="color:#a6e22e">Phrases</span>()<span style="color:#f92672">...</span>)
}

<span style="color:#a6e22e">output</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Join</span>(<span style="color:#a6e22e">phrases</span>[:], <span style="color:#e6db74">"; "</span>)
<span style="color:#a6e22e">r</span>, <span style="color:#a6e22e">g</span>, <span style="color:#a6e22e">b</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">255</span>, <span style="color:#ae81ff">215</span>, <span style="color:#ae81ff">0</span> <span style="color:#75715e">//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]) } }

Теперь, когда у нас есть строка и основа для того, чтобы каждый персонаж раскрашивался по-разному, пришло время представить радугу.

package main

import ( “fmt” “math” “strings”

<span style="color:#e6db74">"github.com/enodata/faker"</span>

)

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

func main() { var phrases []string

<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span>; <span style="color:#a6e22e">i</span> &lt; <span style="color:#ae81ff">3</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> {
    <span style="color:#a6e22e">phrases</span> = append(<span style="color:#a6e22e">phrases</span>, <span style="color:#a6e22e">faker</span>.<span style="color:#a6e22e">Hacker</span>().<span style="color:#a6e22e">Phrases</span>()<span style="color:#f92672">...</span>)
}

<span style="color:#a6e22e">output</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Join</span>(<span style="color:#a6e22e">phrases</span>[:], <span style="color:#e6db74">"; "</span>)

<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">j</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">j</span> &lt; len(<span style="color:#a6e22e">output</span>); <span style="color:#a6e22e">j</span><span style="color:#f92672">++</span> {
    <span style="color:#a6e22e">r</span>, <span style="color:#a6e22e">g</span>, <span style="color:#a6e22e">b</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">rgb</span>(<span style="color:#a6e22e">j</span>)
    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"\033[38;2;%d;%d;%dm%c\033[0m"</span>, <span style="color:#a6e22e">r</span>, <span style="color:#a6e22e">g</span>, <span style="color:#a6e22e">b</span>, <span style="color:#a6e22e">output</span>[<span style="color:#a6e22e">j</span>])
}
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>()

}

Это стиль!

Цвет радуги создается с помощьюrgb()функция, реализованная в исходном исходном коде Ruby вhttps://github.com/busyloop/lolcat/blob/master/lib/lolcat/lol.rb

Теперь давайте отредактируем программу и вместо того, чтобы предоставлять собственный вывод, позвольте ейработать как трубадля других программ. Он будет читать контент из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(ffloat64(i)+0)127 + 128), int(math.Sin(ffloat64(i)+2math.Pi/3)127 + 128), int(math.Sin(ffloat64(i)+4math.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

<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Mode</span>()<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">ModeCharDevice</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"The command is intended to work with pipes."</span>)
    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"Usage: fortune | gorainbow"</span>)
}

<span style="color:#a6e22e">reader</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">bufio</span>.<span style="color:#a6e22e">NewReader</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdin</span>)
<span style="color:#66d9ef">for</span> {
    <span style="color:#a6e22e">input</span>, <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">reader</span>.<span style="color:#a6e22e">ReadRune</span>()
    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
        <span style="color:#66d9ef">break</span>
    }
    <span style="color:#a6e22e">output</span> = append(<span style="color:#a6e22e">output</span>, <span style="color:#a6e22e">input</span>)
}

print(<span style="color:#a6e22e">output</span>)

}

Читает по одной руне изos.Stdinи добавляет его вoutputкусок рун.

Рендеринг вывода был извлечен в print (), но мы также можем передать каждую руну «точно вовремя» по мере ее сканирования:

package main

import ( “bufio” “fmt” “io” “math” “os” )

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

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

<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Mode</span>()<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">ModeCharDevice</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"The command is intended to work with pipes."</span>)
    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"Usage: fortune | gorainbow"</span>)
}

<span style="color:#a6e22e">reader</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">bufio</span>.<span style="color:#a6e22e">NewReader</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdin</span>)
<span style="color:#a6e22e">j</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>
<span style="color:#66d9ef">for</span> {
    <span style="color:#a6e22e">input</span>, <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">reader</span>.<span style="color:#a6e22e">ReadRune</span>()
    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
        <span style="color:#66d9ef">break</span>
    }
    <span style="color:#a6e22e">r</span>, <span style="color:#a6e22e">g</span>, <span style="color:#a6e22e">b</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">rgb</span>(<span style="color:#a6e22e">j</span>)
    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"\033[38;2;%d;%d;%dm%c\033[0m"</span>, <span style="color:#a6e22e">r</span>, <span style="color:#a6e22e">g</span>, <span style="color:#a6e22e">b</span>, <span style="color:#a6e22e">input</span>)
    <span style="color:#a6e22e">j</span><span style="color:#f92672">++</span>
}

}

Это работает так же, как и раньше.

Теперь мы можем развлекаться удачей икоровье высказывание

Давайте сделаем это общесистемной командой, запустивgo buildиgo install. Команда будет запущена какgololcat, поскольку мы использовали это как имя папки.


Больше руководств по go: