From 6c260e654d98fe0176dceb509f8e6305a1352c07 Mon Sep 17 00:00:00 2001 From: Peter Stuifzand Date: Sun, 8 Aug 2021 23:44:24 +0200 Subject: [PATCH] Parse recursive metadata in pages --- search.go | 111 ++++++++++++++++++++++++++++++++++++++++++++++++------ util.go | 10 ++--- 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/search.go b/search.go index 57ed4a3..3111776 100644 --- a/search.go +++ b/search.go @@ -48,11 +48,11 @@ type nameLine struct { } type searchObject struct { - Title string `json:"title"` - Blocks []string `json:"blocks"` - Refs []nameLine `json:"refs"` - Meta map[string]string `json:"meta"` - Links []ParsedLink `json:"links"` + Title string `json:"title"` + Blocks []string `json:"blocks"` + Refs []nameLine `json:"refs"` + Meta map[string]interface{} `json:"meta"` + Links []ParsedLink `json:"links"` } func NewSearchHandler(searchIndex bleve.Index) (http.Handler, error) { @@ -294,26 +294,98 @@ func createSearchObjects(rootBlockID string) ([]pageBlock, error) { func createStructuredFormat(page Page) (searchObject, error) { so := searchObject{} so.Title = page.Title - so.Meta = make(map[string]string) + so.Meta = make(map[string]interface{}) type simpleListItem struct { - Text string - ID string + Text string + ID string + Indented int } + type parent struct { + key string + indent int + items []interface{} + values map[string]interface{} + } + + var parents []parent + parents = append(parents, parent{ + values: make(map[string]interface{}), + }) + var listItems []simpleListItem if err := json.NewDecoder(strings.NewReader(page.Content)).Decode(&listItems); err != nil { so.Blocks = append(so.Blocks, page.Content) } else { for _, li := range listItems { meta := strings.SplitN(li.Text, "::", 2) + par := parents[len(parents)-1] + // merge up + for len(parents) > 1 && li.Indented <= par.indent { + parents = parents[:len(parents)-1] + nextTop := parents[len(parents)-1] + if len(par.values) > 0 { + if vals, e := nextTop.values[par.key]; e { + if vals2, ok := vals.(map[string]interface{}); ok { + for k, v := range par.values { + vals2[k] = v + } + nextTop.values[par.key] = vals2 + } + } else { + nextTop.values[par.key] = par.values + } + } else if len(par.items) > 0 { + nextTop.values[par.key] = par.items + } else { + nextTop.values[par.key] = "" + } + parents[len(parents)-1] = nextTop + par = parents[len(parents)-1] + } if len(meta) == 2 { key := strcase.ToSnake(strings.TrimSpace(meta[0])) value := strings.TrimSpace(meta[1]) - if key == "title" { - so.Title = value + if value == "" { + parents = append(parents, parent{ + key: key, + indent: li.Indented, + values: make(map[string]interface{}), + }) + } else { + if len(parents) > 0 { + par = parents[len(parents)-1] + // save new value + if li.Indented > par.indent { + links, err := ParseLinks(li.ID, value) + if err != nil { + par.values[key] = value + } else { + if len(links) > 0 { + links[0].Href = fmt.Sprintf("%s%s", *baseurl, links[0].PageName) + links[0].ID = "" + par.values[key] = links[0] + } else { + par.values[key] = value + } + } + } + parents[len(parents)-1] = par + } } - so.Meta[key] = value + } else { + links, err := ParseLinks(li.ID, li.Text) + if err != nil { + par.items = append(par.items, li.Text) + } else if len(links) > 0 { + links[0].Href = fmt.Sprintf("%s%s", *baseurl, links[0].PageName) + links[0].ID = "" + par.items = append(par.items, links[0]) + } else { + par.items = append(par.items, li.Text) + } + parents[len(parents)-1] = par } so.Blocks = append(so.Blocks, li.Text) @@ -331,6 +403,23 @@ func createStructuredFormat(page Page) (searchObject, error) { } } + // merge up + for len(parents) > 1 { + par := parents[len(parents)-1] + parents = parents[:len(parents)-1] + nextTop := parents[len(parents)-1] + if len(par.values) > 0 { + nextTop.values[par.key] = par.values + } else if len(par.items) > 0 { + nextTop.values[par.key] = par.items + } else { + nextTop.values[par.key] = "" + } + parents[len(parents)-1] = nextTop + } + + so.Meta = parents[0].values + for _, refs := range page.Refs { for _, ref := range refs { so.Refs = append(so.Refs, nameLine{ diff --git a/util.go b/util.go index 72a29f3..de00a44 100644 --- a/util.go +++ b/util.go @@ -53,11 +53,11 @@ var ( ) type ParsedLink struct { - ID string `json:"ID"` - Name string `json:"title"` - PageName string `json:"name"` - Line string `json:"line"` - Href string `json:"href"` + ID string `json:"ID,omitempty"` + Name string `json:"title,omitempty"` + PageName string `json:"name,omitempty"` + Line string `json:"line,omitempty"` + Href string `json:"href,omitempty"` } const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"