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:
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), ¬e); 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] = ¬e
+ 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[
+ }
+}