wiki/backref.go

150 lines
3.0 KiB
Go
Raw Normal View History

2020-05-07 13:20:36 +00:00
package main
import (
"encoding/json"
"fmt"
2020-05-18 20:09:48 +00:00
"html/template"
2020-07-01 15:36:36 +00:00
"log"
2020-05-07 13:20:36 +00:00
"os"
"path/filepath"
2020-07-01 15:36:36 +00:00
"regexp"
2020-05-07 13:20:36 +00:00
"strings"
)
type Reference struct {
Link ParsedLink
Name string
}
type Refs map[string][]Reference
2020-05-07 13:20:36 +00:00
func processBackrefs(dirname string, page Page) error {
filename := filepath.Join(dirname, "backrefs.json")
2020-05-07 13:20:36 +00:00
refs := make(Refs)
err := loadBackrefs(filename, refs)
2020-05-07 13:20:36 +00:00
if err != nil {
return fmt.Errorf("while loading backrefs: %w", err)
2020-05-07 13:20:36 +00:00
}
err = processBackrefsForPage(page, refs)
if err != nil {
return fmt.Errorf("while processing backrefs for %q: %w", page.Name, err)
}
if err = saveBackrefs(filename, refs); err != nil {
return fmt.Errorf("while saving backrefs: %w", err)
}
return nil
}
func saveBackrefs(filename string, refs Refs) error {
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
return json.NewEncoder(f).Encode(&refs)
}
func processBackrefsForPage(page Page, refs Refs) error {
content := page.Content
2020-05-07 13:20:36 +00:00
2020-07-01 14:40:10 +00:00
var listItems []ListItem
2020-05-07 13:20:36 +00:00
var links []ParsedLink
err := json.NewDecoder(strings.NewReader(content)).Decode(&listItems)
if err == nil {
for _, item := range listItems {
2020-07-01 14:40:10 +00:00
foundLinks, err := ParseLinks(item.ID, item.Text)
if err != nil {
continue
}
links = append(links, foundLinks...)
}
} else {
links, err = ParseLinks(page.Name, page.Content)
if err != nil {
return err
2020-05-07 13:20:36 +00:00
}
}
link:
for _, link := range links {
for i, ref := range refs[link.PageName] {
2020-06-30 22:55:33 +00:00
if ref.Link.ID == link.ID {
refs[link.PageName][i].Link = link
continue link
}
}
refs[link.PageName] = append(refs[link.PageName], Reference{link, page.Name})
}
2020-05-07 13:20:36 +00:00
return nil
2020-05-07 13:20:36 +00:00
}
func getBackrefs(fp *FilePages, p string) (map[string][]Backref, error) {
2020-05-07 13:20:36 +00:00
refs := make(Refs)
p = strings.Replace(p, " ", "_", -1)
filename := filepath.Join(fp.dirname, "backrefs.json")
err := loadBackrefs(filename, refs)
2020-05-07 13:20:36 +00:00
if err != nil {
return nil, err
}
2020-05-16 20:27:48 +00:00
result := make(map[string][]Backref)
2020-05-08 15:21:39 +00:00
for _, ref := range refs[p] {
title := strings.Replace(ref.Name, "_", " ", -1)
2020-05-16 20:27:48 +00:00
if _, e := result[ref.Name]; !e {
result[ref.Name] = nil
}
2020-06-28 20:04:14 +00:00
line := strings.TrimLeft(ref.Link.Line, " ")
if line[0] == '*' && line[1] == ' ' {
line = line[2:]
}
2020-07-01 15:36:36 +00:00
metaKV, err := regexp.Compile(`(\w+)::\s+(.*)`)
if err != nil {
log.Fatal(err)
}
line = metaKV.ReplaceAllString(line, "**[[$1]]**: $2")
pageText := renderMarkdown2(renderLinks(line, false))
editPageText := renderMarkdown2(renderLinks(line, true))
2020-05-24 18:40:41 +00:00
2020-05-31 20:08:36 +00:00
removeBrackets := func(r rune) rune {
if r == '[' || r == ']' || r == '*' {
return -1
}
return r
}
2020-05-16 20:27:48 +00:00
result[ref.Name] = append(result[ref.Name], Backref{
2020-10-21 18:49:23 +00:00
Name: ref.Name,
Title: title,
LineHTML: template.HTML(pageText),
LineEditHTML: template.HTML(editPageText),
2020-10-21 18:49:23 +00:00
Line: strings.Map(removeBrackets, ref.Link.Line),
2020-05-08 15:21:39 +00:00
})
}
return result, nil
2020-05-07 13:20:36 +00:00
}
func loadBackrefs(filename string, refs Refs) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
err = json.NewDecoder(f).Decode(&refs)
if err != nil {
return err
}
return nil
}