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} }
|