Parse recursive metadata in pages

This commit is contained in:
Peter Stuifzand 2021-08-08 23:44:24 +02:00
parent 86ea8ceaf9
commit 6c260e654d
2 changed files with 105 additions and 16 deletions

View File

@ -51,7 +51,7 @@ type searchObject struct {
Title string `json:"title"`
Blocks []string `json:"blocks"`
Refs []nameLine `json:"refs"`
Meta map[string]string `json:"meta"`
Meta map[string]interface{} `json:"meta"`
Links []ParsedLink `json:"links"`
}
@ -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
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
}
so.Meta[key] = value
}
}
parents[len(parents)-1] = par
}
}
} 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{

10
util.go
View File

@ -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"