-
Notifications
You must be signed in to change notification settings - Fork 4
/
service.go
90 lines (81 loc) · 2.15 KB
/
service.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Package help - Content managed by Project Forge, see [projectforge.md] for details.
package help
import (
"slices"
"strings"
"github.com/gomarkdown/markdown"
"github.com/pkg/errors"
"projectforge.dev/projectforge/app/util"
"projectforge.dev/projectforge/help"
)
type Service struct {
Entries Entries
}
func NewService(logger util.Logger) *Service {
entries, err := loadEntries(logger)
if err != nil {
logger.Warnf("unable to load help entries: %+v", err)
}
logger.Debugf("loaded [%d] help entries", len(entries))
return &Service{Entries: entries}
}
func (s *Service) Entry(key string) *Entry {
return s.Entries.Get(key)
}
func (s *Service) Contains(key string) bool {
return s.Entry(key) != nil
}
func loadEntries(logger util.Logger) (Entries, error) {
keys, err := help.List()
if err != nil {
logger.Errorf("unable to build documentation menu: %+v", err)
}
hd, ft := "", ""
if slices.Contains(keys, "_header") {
hd, _ = help.Content("_header.md")
}
if slices.Contains(keys, "_footer") {
ft, _ = help.Content("_footer.md")
}
ret := make(Entries, 0, len(keys))
for _, key := range keys {
if key == "_header" || key == "_footer" {
continue
}
ent, err := entryFor(key, hd, ft, 4)
if err != nil {
return nil, errors.Wrapf(err, "unable to load help file [%s]", key)
}
if ent != nil && !strings.Contains(ent.Title, "!") {
ret = append(ret, ent)
}
}
return ret, nil
}
func entryFor(key string, hd string, ft string, indent int) (*Entry, error) {
path := key
if !strings.HasSuffix(path, util.ExtMarkdown) {
path += util.ExtMarkdown
}
md, err := help.Content(path)
if err != nil {
return nil, err
}
title := ""
if strings.HasPrefix(md, "#") {
if idx := strings.Index(md, "\n"); idx > -1 {
title = strings.TrimSpace(strings.ReplaceAll(md[:idx], "#", ""))
md = strings.TrimSpace(md[idx:])
}
}
const dblLB = "\n\n"
if hd != "" {
md = hd + dblLB + md
}
if ft != "" {
md += dblLB + ft
}
html := strings.TrimSpace(string(markdown.ToHTML([]byte(md), nil, nil)))
html = strings.Join(util.StringSplitLinesIndented(html, indent, false, false), "\n")
return &Entry{Key: key, Title: title, Markdown: md, HTML: html}, nil
}