-
Notifications
You must be signed in to change notification settings - Fork 0
/
vault.go
136 lines (113 loc) · 2.98 KB
/
vault.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package goboe
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/samxsmith/goboe/pkg/linkmanagement"
)
type Vault struct {
notes map[string]Note
linkRegistry linkmanagement.LinkRegistry
root string
}
func OpenVault(vaultRoot, frontMatterFilter string) (Vault, error) {
notes, err := traverseVault(vaultRoot)
if err != nil {
return Vault{}, fmt.Errorf("traverseVault: %w", err)
}
v := newVault(vaultRoot)
for _, notePath := range notes {
note, err := OpenNote(notePath)
if err != nil {
return v, fmt.Errorf("OpenNote: %w", err)
}
v.notes[note.name] = note
}
// do this before generating link registry
if frontMatterFilter != "" {
v.ApplyFrontMatterFilter(frontMatterFilter)
}
// now we have all notes in a map, and we've applied filters
// we can do another pass to assemble backlinks
v.generateLinks()
return v, nil
}
func newVault(root string) Vault {
v := Vault{}
v.root = root
v.notes = map[string]Note{}
v.linkRegistry = linkmanagement.NewLinkRegistry()
return v
}
func traverseVault(vaultRoot string) ([]string, error) {
var noteList []string
err := filepath.Walk(vaultRoot, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
if strings.HasPrefix(info.Name(), ".") {
return filepath.SkipDir
}
return nil
}
filename := info.Name()
ext := filepath.Ext(filename)
if ext != ".md" {
return nil
}
noteList = append(noteList, path)
return nil
})
return noteList, err
}
func (v *Vault) ApplyFrontMatterFilter(desiredFrontMatterKey string) {
for noteName, note := range v.notes {
if _, ok := note.frontMatter[desiredFrontMatterKey]; !ok {
delete(v.notes, noteName)
}
}
}
func (v *Vault) generateLinks() {
for _, note := range v.notes {
linksInThisNote := note.linkedNoteNames
var links []linkmanagement.Link
for _, linkedNoteFileName := range linksInThisNote {
linkedNoteName := strings.TrimSuffix(linkedNoteFileName, filepath.Ext(linkedNoteFileName))
link := linkmanagement.Link{
Name: linkedNoteFileName,
PathFromRoot: v.LinkFromVaultRoot(linkedNoteName),
}
links = append(links, link)
}
// not necessary at this point, but may wish to record this link direction in future
noteLink := linkmanagement.Link{
Name: note.name,
PathFromRoot: v.LinkFromVaultRoot(note.name),
}
v.linkRegistry.RegisterLinks(noteLink, links)
}
}
func (v *Vault) Notes() []Note {
notes := make([]Note, len(v.notes))
i := 0
for _, n := range v.notes {
notes[i] = n
i++
}
return notes
}
func (v *Vault) GetLinkRegistry() linkmanagement.LinkRegistry {
return v.linkRegistry
}
func (v *Vault) LinkFromVaultRoot(noteName string) string {
note, ok := v.notes[noteName]
if !ok {
return ""
}
noteDir := filepath.Dir(note.Path())
noteOutputFilename := fmt.Sprintf("%s.html", note.Name())
noteDirRelativeToVaultRoot, _ := filepath.Rel(v.root, noteDir)
return filepath.Join(noteDirRelativeToVaultRoot, noteOutputFilename)
}