package core import ( "encoding/json" "fmt" "path/filepath" "regexp" "time" ) // NoteFormatter formats notes to be printed on the screen. type NoteFormatter func(note ContextualNote) (string, error) func newNoteFormatter(basePath string, template Template, linkFormatter LinkFormatter, fs FileStorage) (NoteFormatter, error) { termRepl, err := template.Styler().Style("$1", StyleTerm) if err != nil { return nil, err } return func(note ContextualNote) (string, error) { path, err := fs.Rel(filepath.Join(basePath, note.Path)) if err != nil { return "", err } snippets := make([]string, 0) for _, snippet := range note.Snippets { snippets = append(snippets, noteTermRegex.ReplaceAllString(snippet, termRepl)) } return template.Render(noteFormatRenderContext{ Path: path, Title: note.Title, Link: newLazyStringer(func() string { link, _ := linkFormatter(path, note.Title) return link }), Lead: note.Lead, Body: note.Body, Snippets: snippets, Tags: note.Tags, RawContent: note.RawContent, WordCount: note.WordCount, Metadata: note.Metadata, Created: note.Created, Modified: note.Modified, Checksum: note.Checksum, }) }, nil } var noteTermRegex = regexp.MustCompile(`(.*?)`) // noteFormatRenderContext holds the variables available to the note formatting // templates. type noteFormatRenderContext struct { Path string Title string Link fmt.Stringer Lead string Body string Snippets []string RawContent string `handlebars:"raw-content"` WordCount int `handlebars:"word-count"` Tags []string Metadata map[string]interface{} Created time.Time Modified time.Time Checksum string Env map[string]string } func (c noteFormatRenderContext) Equal(other noteFormatRenderContext) bool { json1, err := json.Marshal(c) if err != nil { return false } json2, err := json.Marshal(other) if err != nil { return false } return string(json1) == string(json2) }