2020-05-07 13:20:36 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2020-06-30 20:56:12 +00:00
|
|
|
"fmt"
|
2020-05-18 20:09:48 +00:00
|
|
|
"html/template"
|
2020-05-07 13:20:36 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2020-05-16 19:02:19 +00:00
|
|
|
type Reference struct {
|
|
|
|
Link ParsedLink
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
|
|
|
|
type Refs map[string][]Reference
|
2020-05-07 13:20:36 +00:00
|
|
|
|
2020-06-30 20:56:12 +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)
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
err := loadBackrefs(filename, refs)
|
2020-05-07 13:20:36 +00:00
|
|
|
if err != nil {
|
2020-06-30 20:56:12 +00:00
|
|
|
return fmt.Errorf("while loading backrefs: %w", err)
|
2020-05-07 13:20:36 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
err = processBackrefsForPage(page, refs)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("while processing backrefs for %q: %w", page.Name, err)
|
|
|
|
}
|
2020-05-16 19:02:19 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
if err = saveBackrefs(filename, refs); err != nil {
|
|
|
|
return fmt.Errorf("while saving backrefs: %w", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2020-05-16 19:02:19 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
func saveBackrefs(filename string, refs Refs) error {
|
|
|
|
f, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
2020-05-16 19:02:19 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
return json.NewEncoder(f).Encode(&refs)
|
|
|
|
}
|
2020-05-16 19:02:19 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
func processBackrefsForPage(page Page, refs Refs) error {
|
|
|
|
content := page.Content
|
2020-05-07 13:20:36 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
var listItems []struct {
|
|
|
|
Indented int
|
|
|
|
Text string
|
|
|
|
}
|
2020-05-07 13:20:36 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
err := json.NewDecoder(strings.NewReader(content)).Decode(&listItems)
|
|
|
|
if err == nil {
|
|
|
|
pageText := ""
|
|
|
|
for _, item := range listItems {
|
|
|
|
pageText += strings.Repeat(" ", item.Indented) + "* " + item.Text + "\n"
|
2020-05-07 13:20:36 +00:00
|
|
|
}
|
2020-06-30 20:56:12 +00:00
|
|
|
|
|
|
|
content = pageText
|
2020-05-07 13:20:36 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
links, err := ParseLinks(content)
|
|
|
|
|
2020-05-07 13:20:36 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
for _, link := range links {
|
|
|
|
// FIXME: this produces duplicates
|
|
|
|
refs[link.PageName] = append(refs[link.PageName], Reference{link, page.Name})
|
|
|
|
}
|
2020-05-07 13:20:36 +00:00
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
return nil
|
2020-05-07 13:20:36 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 20:56:12 +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)
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
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] {
|
2020-05-16 19:02:19 +00:00
|
|
|
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:]
|
|
|
|
}
|
|
|
|
links := renderLinks(line)
|
2020-05-24 18:40:41 +00:00
|
|
|
pageText := renderMarkdown2(links)
|
|
|
|
|
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-05-31 20:08:36 +00:00
|
|
|
Name: ref.Name,
|
|
|
|
Title: title,
|
|
|
|
LineHTML: template.HTML(pageText),
|
2020-06-28 20:04:14 +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
|
|
|
}
|
2020-06-30 20:56:12 +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
|
|
|
|
}
|