-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrender.go
75 lines (69 loc) · 1.94 KB
/
render.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main
import (
"fmt"
"strings"
forest "git.sr.ht/~whereswaldon/forest-go"
"github.com/gdamore/tcell"
)
// nodeState represents possible render states for nodes
type nodeState uint
const (
none nodeState = iota
ancestor
descendant
current
)
// renderConfig holds information about how a particular node should be rendered
type renderConfig struct {
state nodeState
}
// renderNode transforms `node` into a slice of rendered lines, using `store` to look up nodes referenced
// by `node` and `config` to make style choices.
func renderNode(node forest.Node, store forest.Store, config renderConfig) ([]RenderedLine, error) {
var (
ancestorColor = tcell.StyleDefault.Foreground(tcell.ColorYellow)
descendantColor = tcell.StyleDefault.Foreground(tcell.ColorGreen)
currentColor = tcell.StyleDefault.Foreground(tcell.ColorRed)
conversationRootColor = tcell.StyleDefault.Foreground(tcell.ColorTeal)
)
var out []RenderedLine
var style tcell.Style
switch n := node.(type) {
case *forest.Reply:
author, present, err := store.Get(&n.Author)
if err != nil {
return nil, err
} else if !present {
return nil, fmt.Errorf("Node %s is not in the store", n.Author.String())
}
asIdent := author.(*forest.Identity)
switch config.state {
case ancestor:
style = ancestorColor
case descendant:
style = descendantColor
case current:
style = currentColor
default:
style = tcell.StyleDefault
}
rendered := fmt.Sprintf("%s:\n%s", string(asIdent.Name.Blob), string(n.Content.Blob))
// drop all trailing newline characters
for rendered[len(rendered)-1] == "\n"[0] {
rendered = rendered[:len(rendered)-1]
}
for _, line := range strings.Split(rendered, "\n") {
out = append(out, RenderedLine{
ID: n.ID(),
Style: style,
Text: []rune(line),
})
}
if n.Depth == 1 {
out[0].Style = conversationRootColor
} else {
out[0].Style = tcell.StyleDefault
}
}
return out, nil
}