Doc Browser

/app/controller/cmenu/docs.go (2.2 KB)

 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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package cmenu

import (
"cmp"
"io/fs"
"path"
"slices"
"strings"

"github.com/samber/lo"

"{{{ .Package }}}/app/lib/menu"
"{{{ .Package }}}/app/util"
"{{{ .Package }}}/doc"
)

var docMenuCached *menu.Item

func docMenu(logger util.Logger) *menu.Item {
if docMenuCached == nil {
docMenuCached = docMenuCreate(logger)
}
return docMenuCached
}

func docMenuCreate(logger util.Logger) *menu.Item {
var paths []string
err := fs.WalkDir(doc.FS, ".", func(path string, d fs.DirEntry, err error) error {
paths = append(paths, path)
return err
})
if err != nil {
logger.Errorf("unable to build documentation menu: %+v", err)
}
slices.Sort(paths)

ret := &menu.Item{Key: "docs", Title: "Documentation", Icon: "folder"}
for _, p := range paths {
if p == "." || !strings.HasSuffix(p, ".md") {
continue
}
split := util.StringSplitAndTrim(p, "/")
p = strings.TrimSuffix(p, ".md")
mi := ret
lo.ForEach(split, func(comp string, idx int) {
name := strings.TrimSuffix(comp, ".md")
addFolder := func() {
i := &menu.Item{Key: name, Title: util.StringToCamel(name), Icon: "folder"}
mi.Children = append(mi.Children, i)
slices.SortFunc(mi.Children, func(l *menu.Item, r *menu.Item) int {
return cmp.Compare(l.Title, r.Title)
})
mi = i
}
if idx == len(split)-1 {
if strings.HasSuffix(comp, ".md") {
mi.Children = append(mi.Children, addChild(p, name))
} else {
addFolder()
}
} else {
if kid := mi.Children.Get(comp); kid == nil {
addFolder()
} else {
mi = kid
}
}
})
}
slices.SortFunc(ret.Children, func(l *menu.Item, r *menu.Item) int {
return cmp.Compare(l.Title, r.Title)
})

return ret
}

func addChild(p string, name string) *menu.Item {
r := "/" + path.Join("docs", p)
title := util.StringToCamel(name)
b, err := doc.FS.ReadFile(p + ".md")
if err != nil {
panic(err)
}

lines := util.StringSplitLines(string(b))
for _, line := range lines {
if strings.HasPrefix(line, "#") {
for strings.HasPrefix(line, "#") {
line = line[1:]
}
title = strings.TrimSpace(line)
break
}
}

return &menu.Item{Key: name, Title: title, Icon: "file", Route: r}
}