Last active
January 17, 2020 16:04
-
-
Save tiborvass/78a400028bab4fa5b423f100b1e0eee1 to your computer and use it in GitHub Desktop.
Script to show fake demos with monkey typing: go run demo.go path/to/textfile [number_of_steps_to_skip]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"io" | |
"log" | |
"math/rand" | |
"os" | |
"os/exec" | |
"strconv" | |
"strings" | |
"time" | |
term "github.com/nsf/termbox-go" | |
) | |
func main() { | |
if len(os.Args) > 2 { | |
i, err := strconv.Atoi(os.Args[2]) | |
if err != nil { | |
log.Fatal(err) | |
} | |
stepsToSkip = i | |
} | |
var f *os.File | |
var err error | |
if len(os.Args) > 1 { | |
f, err = os.Open(os.Args[1]) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer f.Close() | |
} | |
if err := term.Init(); err != nil { | |
panic(err) | |
} | |
defer term.Close() | |
defer func() { | |
if x := recover(); x != nil { | |
if _, ok := x.(exit); ok { | |
return | |
} | |
panic(x) | |
} | |
}() | |
if err := read(f); err != nil { | |
log.Fatal(err) | |
} | |
} | |
type mode int | |
const ( | |
modeNormal mode = iota | |
modeType | |
modeExec | |
modeANSI | |
) | |
type printer struct { | |
mode mode | |
} | |
func read(f io.Reader) error { | |
// show cursor | |
os.Stdout.Write(append([]byte{27}, []byte("[?25h")...)) | |
s := bufio.NewScanner(f) | |
p := &printer{} | |
for s.Scan() { | |
t := s.Text() | |
p.print(t) | |
} | |
return s.Err() | |
} | |
func ansi(s string) mode { | |
os.Stdout.Write([]byte{27}) | |
os.Stdout.WriteString(s) | |
return modeANSI | |
} | |
func (p *printer) print(t string) { | |
if len(t) > 0 { | |
switch p.mode { | |
case modeNormal: | |
if i := strings.Index(t, "#{{"); i >= 0 { | |
fmt.Print(t[:i]) | |
//pause() | |
t = t[i+3:] | |
j := strings.Index(t, ":") | |
if j < 0 { | |
panic("could not find ':' in #{{...}}") | |
} | |
switch t[:j] { | |
case "ansi": | |
k := strings.Index(t[j+1:], "}}") | |
if j < 0 { | |
panic("wtf") | |
} | |
p.mode = ansi(t[j+1 : j+1+k]) | |
t = t[j+1+k:] | |
p.print(t) | |
return | |
case "underline": | |
p.mode = ansi("[4m") | |
case "reverse": | |
p.mode = ansi("[7m") | |
case "bold": | |
p.mode = ansi("[1m") | |
case "darkgrey": | |
p.mode = ansi("[38;5;236m") | |
case "exec": | |
p.mode = modeExec | |
case "type": | |
p.mode = modeType | |
} | |
t = t[j+1:] | |
p.print(t) | |
return | |
} else { | |
fmt.Print(t) | |
} | |
case modeType, modeExec: | |
if i := strings.Index(t, "}}"); i >= 0 { | |
if p.mode == modeExec { | |
if counter >= stepsToSkip { | |
cmd := exec.Command("sh", "-c", t[:i]) | |
cmd.Stdin = os.Stdin | |
cmd.Stdout = os.Stdout | |
cmd.Stderr = os.Stderr | |
cmd.Run() | |
} | |
} else { | |
slowprint(t[:i]) | |
} | |
t = t[i+2:] | |
//pause() | |
p.mode = modeNormal | |
p.print(t) | |
return | |
} else { | |
slowprint(t) | |
} | |
case modeANSI: | |
if i := strings.Index(t, "}}"); i >= 0 { | |
fmt.Print(t[:i]) | |
os.Stdout.Write([]byte{27, 91, '0', 'm'}) | |
p.mode = modeNormal | |
t = t[i+2:] | |
p.print(t) | |
return | |
} | |
} | |
} | |
fmt.Println() | |
return | |
} | |
func typingSleep() { | |
time.Sleep(time.Millisecond * time.Duration(rand.Int63n(100))) | |
} | |
func slowprint(s string) { | |
for _, r := range s { | |
pause(false) | |
//typingSleep() | |
fmt.Print(string(r)) | |
} | |
pause(true) | |
} | |
type exit struct{} | |
var counter, stepsToSkip int | |
func pause(expectEnter bool) { | |
if stepsToSkip > 0 { | |
counter++ | |
if counter < stepsToSkip { | |
return | |
} | |
} | |
for { | |
switch ev := term.PollEvent(); ev.Type { | |
case term.EventKey: | |
switch ev.Key { | |
case term.KeyCtrlC: | |
panic(exit{}) | |
case term.KeyEnter: | |
return | |
default: | |
if !expectEnter { | |
return | |
} | |
} | |
case term.EventError: | |
panic(ev.Err) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment