/
entry.go
66 lines (53 loc) · 1.36 KB
/
entry.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
package journal
import (
"errors"
"path"
"regexp"
"strings"
"time"
)
var errNotEntry = errors.New("not a journal entry")
var reEntryFile = regexp.MustCompile(`(\d{4}-\d{2}-\d{2})(-.*)?\.md`)
// Entry is a file in the journal and its associated tags.
type Entry struct {
Time time.Time
File string
// Linked list of tags.
FirstTag *tagNode
name string
}
// NewEntry returns a new Entry.
func NewEntry(file string) (e Entry, err error) {
matches := reEntryFile.FindStringSubmatch(path.Base(file))
if len(matches) == 0 {
err = errNotEntry
return e, err
}
e.Time, err = time.Parse(dateFormat, matches[1])
if err != nil {
return e, err
}
e.name = matches[2]
e.File = file
return e, nil
}
// Title returns a title for the entry. It uses the first heading if one
// exists. If no heading is found, it uses the portion of the entry's filename
// after the date as the title. In the latter case, dashes (`-`) and
// underscores (`_`) are converted to spaces, and the first letter of each word
// is capitalized.
func (e Entry) Title() string {
for n := e.FirstTag; n != nil; n = n.next {
if n.Kind() == "title" {
return n.TagName
}
}
if title := e.name; title != "" {
title = strings.ReplaceAll(title, "-", " ")
title = strings.ReplaceAll(title, "_", " ")
title = strings.Title(title)
title = strings.TrimSpace(title)
return title
}
return ""
}