dotfiles

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 8ea7ddddae3d5bcb15bcf43423f5020dd6014fdd (tree)
parent d68ff22267c76ce4c2bf45990da0ddaf04b45df2
Author: Motiejus Jakštys <desired.mta@gmail.com>
Date:   Mon,  8 Jun 2020 13:38:01 +0300

wip traversing

Diffstat:
Msrc/joplin2site/internal/html/html.go | 28+++++++++++++++++++++++-----
Msrc/joplin2site/internal/note/note.go | 40+++++++++++++++++++++++++++++-----------
Msrc/joplin2site/internal/page/page.go | 55+++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 95 insertions(+), 28 deletions(-)

diff --git a/src/joplin2site/internal/html/html.go b/src/joplin2site/internal/html/html.go @@ -3,18 +3,36 @@ package html import ( "fmt" - "github.com/motiejus/dotfiles/joplin2site/internal/note" + inote "github.com/motiejus/dotfiles/joplin2site/internal/note" + ipage "github.com/motiejus/dotfiles/joplin2site/internal/page" ) -type Files map[string][]byte +type ( + // Webpage is the resulting URL -> []byte map. + Webpage map[string][]byte + + // pageContext contains everything that's necessary to render a page. + pageContext struct { + ipage.Page + + Prev *ipage.Page + Next *ipage.Page + } +) // Render accepts a TLD and returns URL -> []bytes mapping. -func Render(dir, tld string) (Files, error) { - notes1, err := note.ListNotes(dir) +func Render(dir, tld string) (Webpage, error) { + notes, err := inote.ListNotes(dir) if err != nil { return nil, fmt.Errorf("failed to get notes: %w", err) } - _, err = notes1.Shake(tld) + tree := inote.BuildTree(notes) + if err := notes.Shake(tree, tld); err != nil { + return nil, err + } + + // Convert all publish-able notes to pages. + pages, err := ipage.ToPublishablePages(notes) if err != nil { return nil, err } diff --git a/src/joplin2site/internal/note/note.go b/src/joplin2site/internal/note/note.go @@ -69,10 +69,12 @@ const ( ) func Parse(in string) (Note, error) { - var title, body, params string titleIdx := strings.Index(in, "\n\n") paramsIdx := strings.LastIndex(in, "\n\n") - title, body, params = in[0:titleIdx], in[min(titleIdx+2, paramsIdx):paramsIdx], in[paramsIdx:] + title, body, params := + in[:titleIdx], + in[min(titleIdx+2, paramsIdx):paramsIdx], + in[paramsIdx:] var note Note if err := yaml.Unmarshal([]byte(params), &note); err != nil { @@ -86,8 +88,8 @@ func Parse(in string) (Note, error) { } type ( - // Notes is a list of notes by ID. - Notes map[string]*Note + // Notes is a map from ID to *Note + Notes map[string]Note // NoteTree is a note hierarchy by ID. NoteTree map[string]NoteChildren @@ -112,28 +114,29 @@ func ListNotes(dir string) (Notes, error) { return nil, fmt.Errorf("failed to parse %q: %w", file.Name(), err) } - notes[note.ID] = &note + notes[note.ID] = note } return notes, nil } // Shake returns a sub-set of notes which eventually parent to "tld" -func (notes Notes) Shake(tld string) (Notes, error) { +func (notes Notes) Shake(tree NoteTree, tld string) error { topID := notes.GetFolderID(tld) if topID == "" { - return nil, fmt.Errorf("tld %q not found", tld) + return fmt.Errorf("tld %q not found", tld) } children := make(NoteChildren) - buildTree(notes).flatten(topID, children) + tree.flatten(topID, children) ret := make(Notes, len(children)) for noteID := range children { ret[noteID] = notes[noteID] } + notes = ret - return ret, nil + return nil } // GetFolderID returns a folder ID for a particular title @@ -151,7 +154,8 @@ func (notes Notes) GetFolderID(title string) string { return parentID } -func buildTree(notes Notes) NoteTree { +// BuildTree builds a note tree. +func BuildTree(notes Notes) NoteTree { ret := make(NoteTree) for _, note := range notes { if _, ok := ret[note.ParentID]; !ok { @@ -162,7 +166,21 @@ func buildTree(notes Notes) NoteTree { return ret } -// flatten returns all children of a tree +// Subtree takes a sub-tree under a given tld. +func (t NoteTree) Subtree(id string) { + var ret NoteTree + subtree(id, ret) + t = ret +} + +func (t NoteTree) subtree(id string, acc NoteTree) { + for cid := range t[id] { + acc[cid] = make(NoteChildren, len(t[cid])) + t.subtree(cid, acc) + } +} + +// flatten returns a flat list of all `id`'s descendants. func (t NoteTree) flatten(id string, acc NoteChildren) { acc[id] = struct{}{} for child := range t { diff --git a/src/joplin2site/internal/page/page.go b/src/joplin2site/internal/page/page.go @@ -7,12 +7,12 @@ import ( "strings" "time" - "github.com/motiejus/dotfiles/joplin2site/internal/note" + inote "github.com/motiejus/dotfiles/joplin2site/internal/note" "gopkg.in/yaml.v2" ) type ( - // Page contains everything that's necessary to render a page. + // Page is a stand-alone converted note. Page struct { ID string Title string @@ -22,11 +22,8 @@ type ( PublishedAt time.Time } - // Pages is a slice of pages. + // Pages is a slice of pages ordered by publish date. Pages []Page - - // PageHierarchy is a map of: folderID -> ordered list of pages. - PageHierarchy map[string][]*Page ) type userMeta struct { @@ -45,7 +42,7 @@ const ( ) // FromNote converts a Joplin Note to a Page -func FromNote(n note.Note) (Page, error) { +func FromNote(n inote.Note) (Page, error) { if !strings.HasPrefix(n.Body, _metaPrefix) { return Page{}, ErrMetaStart } @@ -72,7 +69,7 @@ func FromNote(n note.Note) (Page, error) { } // SubPages returns immediate Pages of a tree -func SubPages(notes note.Notes, title string) (Pages, error) { +func SubPages(notes inote.Notes, title string) (Pages, error) { // Find the parent note that will be the parent of the sub-notebook. parentID := notes.GetFolderID(title) if parentID == "" { @@ -80,14 +77,14 @@ func SubPages(notes note.Notes, title string) (Pages, error) { } var pages Pages - for _, inote := range notes { - if inote.ParentID != parentID { + for _, note := range notes { + if note.ParentID != parentID { continue } - if inote.Type != note.ItemTypeNote { + if note.Type != inote.ItemTypeNote { continue } - page, err := FromNote(*inote) + page, err := FromNote(note) if err != nil { return nil, fmt.Errorf("failed to convert note to page: %w", err) } @@ -101,3 +98,37 @@ func SubPages(notes note.Notes, title string) (Pages, error) { }) return pages, nil } + +// ToPublishablePages returns notes that can be published. +func ToPublishablePages(notes inote.Notes) (Pages, error) { + pages := make([]Page, len(notes)) + for id, note := range notes { + if note.Type != inote.ItemTypeNote { + continue + } + page, err := ipage.FromNote(note) + if err != nil { + return nil, fmt.Errorf("failed to convert note to page: %w", err) + } + if page.PublishedAt.After(time.Now()) { + continue + } + + pages = append(pages, page) + } + return pages, nil +} + +type PrevNext struct { + Prev *page.Page + Next *page.Page +} + +// Sequenced returns sequenced pages within the same folder. +func (pages Pages) Sequenced(tree inote.NoteTree) map[string]PrevNext { + // folders maps folder ID -> set(note id) + var folders map[string]map[string]struct{} + for _, page := range pages { + parent := tree[ + } +}