~skuzzymiglet/greedy

b74607614a59e72a067939af6a928228eb034282 — skuzzymiglet 2 months ago de54bca master
make start/end intervals work correctly
4 files changed, 30 insertions(+), 10 deletions(-)

M README.md
M go.mod
M main.go
M speedread.go
M README.md => README.md +8 -0
@@ 22,4 22,12 @@ greedy https://www.arp242.net/read-stdin.html # read articles from the web
+ `<`: move text left
+ `>`: move text right

# options

```
-p     save position (default true)
-r     try to resume at saved position (default true)
-w int speed (words per minute) (default 400)
```

[![asciicast](https://asciinema.org/a/lgoSRtQU4cbeS33MJu71yNgd6.svg)](https://asciinema.org/a/lgoSRtQU4cbeS33MJu71yNgd6)

M go.mod => go.mod +3 -0
@@ 5,4 5,7 @@ go 1.15
require (
	github.com/gdamore/tcell v1.4.0
	github.com/go-shiori/go-readability v0.0.0-20201011032228-bdc871772408
	golang.org/x/net v0.0.0-20201207224615-747e23833adb // indirect
	golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d // indirect
	gopkg.in/yaml.v2 v2.2.8 // indirect
)

M main.go => main.go +5 -3
@@ 19,14 19,15 @@ var defaultConfig = config{
	wpm:    400,
	strong: tcell.StyleDefault.Bold(true).Foreground(tcell.ColorRed),
	// normal: tcell.StyleDefault.Reverse(true),
	pauses: map[string]time.Duration{
	intervals: map[string]time.Duration{
		".": time.Millisecond * time.Duration(500),
		"(": time.Millisecond * time.Duration(200),
		")": time.Millisecond * time.Duration(200),
		"-": time.Millisecond * time.Duration(300),
		",": time.Millisecond * time.Duration(300),
	},
	pauseEnd: true, pauseStart: true,
	intervalStart: time.Second, intervalEnd: time.Second,
	pauseStart: false, pauseEnd: false,
	left: 10,
}



@@ 63,7 64,7 @@ func main() {
		title = article.Title
		contentHash = sha256.Sum256([]byte(article.TextContent))
		content = strings.Fields(article.TextContent)
		// TODO: handle images, code blocks, links, footnotes and other web stuff
		// TODO: handle images, code blocks, links, footnotes and other web stuff. Or not
	}
	// TODO: cannot resume a file if at end
	conf := defaultConfig


@@ 76,6 77,7 @@ func main() {
		log.Printf("Resuming at word %d\n", p)
		conf.startPos = p
	}
	// TODO: run speedread with a context, so we can survive kills/other signals
	end, err := speedread(content, conf, title)
	if savePos {
		log.Println("Saving position...")

M speedread.go => speedread.go +14 -7
@@ 12,11 12,13 @@ import (
// Currrently, the text is split by whitespace. Paragraphs are bolted onto eachother
type config struct { // TODO: add command line flags for every value here
	pauseEnd, pauseStart bool // TODO: pause when not focused (X11 hacks!)
	startPos             int
	wpm                  int
	pauses               map[string]time.Duration // Determines the pause between words when the according string is found in the word
	normal, strong       tcell.Style
	left                 int // Start of text
	// TODO: remove the bools, always use interval{Start,End} (let main set them to wpm)
	intervalStart, intervalEnd time.Duration
	startPos                   int
	wpm                        int                      // TODO: just turn this into a goddamn time.Duration
	intervals                  map[string]time.Duration // Determines the pause between words when the according string is found in the word
	normal, strong             tcell.Style
	left                       int // Start of text
}

func speedread(content []string, config config, title string) (endPos int, err error) {


@@ 56,7 58,7 @@ func speedread(content []string, config config, title string) (endPos int, err e
		t       time.Duration
	)

	for word < len(content)-1 && word >= 0 {
	for word <= len(content)-1 && word >= 0 {
		if word < 0 {
			panic("negative position")
		}


@@ 101,7 103,12 @@ func speedread(content []string, config config, title string) (endPos int, err e

		// determine how long to wait
		t = func() time.Duration {
			for k, v := range config.pauses {
			if word == 0 {
				return config.intervalStart
			} else if word == len(content)-1 {
				return config.intervalEnd
			}
			for k, v := range config.intervals {
				if strings.Contains(content[word], k) {
					return v
				}