hugo-obsidian/main.go

144 lines
2.8 KiB
Go
Raw Permalink Normal View History

2021-07-17 06:26:40 +03:00
package main
import (
2021-07-17 07:51:06 +03:00
"flag"
2021-07-17 06:26:40 +03:00
md "github.com/nikitavoloboev/markdown-parser"
2021-07-17 07:38:12 +03:00
"gopkg.in/yaml.v3"
2021-07-17 06:26:40 +03:00
"io/fs"
"io/ioutil"
2021-07-17 07:51:06 +03:00
"path"
2021-07-17 06:26:40 +03:00
"path/filepath"
2021-07-17 06:32:47 +03:00
"strings"
2021-07-17 06:26:40 +03:00
)
type Link struct {
Source string
Target string
Text string
}
2021-07-17 07:01:08 +03:00
type LinkTable = map[string][]Link
type Index struct {
Links LinkTable
Backlinks LinkTable
}
2021-07-17 06:32:47 +03:00
func trim(source, prefix, suffix string) string {
return strings.TrimPrefix(strings.TrimSuffix(source, suffix), prefix)
}
// parse single file for links
func parse(dir, pathPrefix string) []Link {
2021-07-17 06:26:40 +03:00
// read file
bytes, err := ioutil.ReadFile(dir)
if err != nil {
panic(err)
}
// parse md
var links []Link
for text, target := range md.GetAllLinks(string(bytes)) {
links = append(links, Link{
2021-07-17 06:32:47 +03:00
Source: trim(dir, pathPrefix, ".md"),
2021-07-17 06:26:40 +03:00
Target: target,
Text: text,
})
}
return links
}
2021-07-17 06:32:47 +03:00
// recursively walk directory and return all files with given extension
2021-07-17 07:01:08 +03:00
func walk(root, ext string) (res []Link) {
2021-07-17 07:51:06 +03:00
println(root)
2021-07-17 07:01:08 +03:00
err := filepath.WalkDir(root, func(s string, d fs.DirEntry, e error) error {
2021-07-17 06:26:40 +03:00
if e != nil {
return e
}
if filepath.Ext(d.Name()) == ext {
2021-07-17 07:01:08 +03:00
res = append(res, parse(s, root)...)
2021-07-17 06:26:40 +03:00
}
return nil
})
2021-07-17 07:01:08 +03:00
if err != nil {
panic(err)
}
return res
}
2021-07-17 07:38:12 +03:00
// filter out certain links (e.g. to media)
func filter(links []Link) (res []Link) {
for _, l := range links {
// filter external and non-md
println(l.Target)
isInternal := strings.HasPrefix(l.Target, "/")
isMarkdown := filepath.Ext(l.Target) == "" || filepath.Ext(l.Target) == ".md"
if isInternal && isMarkdown {
res = append(res, l)
}
}
return res
}
2021-07-17 07:01:08 +03:00
// constructs index from links
func index(links []Link) (index Index) {
linkMap := make(map[string][]Link)
backlinkMap := make(map[string][]Link)
for _, l := range links {
bl := Link{
Source: l.Target,
Target: l.Source,
Text: l.Text,
}
2021-07-17 07:38:12 +03:00
// backlink (only if internal)
2021-07-17 07:01:08 +03:00
if val, ok := backlinkMap[l.Target]; ok {
val = append(val, bl)
} else {
backlinkMap[l.Target] = []Link{bl}
}
2021-07-17 07:38:12 +03:00
// regular link
2021-07-17 07:01:08 +03:00
if val, ok := linkMap[l.Source]; ok {
val = append(val, l)
} else {
linkMap[l.Target] = []Link{l}
}
}
index.Links = linkMap
index.Backlinks = backlinkMap
return index
2021-07-17 06:26:40 +03:00
}
2021-07-17 07:51:06 +03:00
func write(links []Link, out string) error {
index := index(links)
resStruct := struct{
Index Index
Links []Link
}{
Index: index,
Links: links,
}
marshalledIndex, mErr := yaml.Marshal(&resStruct)
2021-07-17 07:38:12 +03:00
if mErr != nil {
return mErr
}
2021-07-17 07:51:06 +03:00
writeErr := ioutil.WriteFile(path.Join(out, "linkIndex.yaml"), marshalledIndex, 0644)
2021-07-17 07:38:12 +03:00
if writeErr != nil {
return writeErr
}
return nil
}
2021-07-17 06:26:40 +03:00
func main() {
2021-07-17 07:51:06 +03:00
in := flag.String("input", ".", "Input Directory")
out := flag.String("output", ".", "Output Directory")
flag.Parse()
l := walk(*in, ".md")
2021-07-17 07:38:12 +03:00
f := filter(l)
2021-07-17 07:51:06 +03:00
err := write(f, *out)
2021-07-17 07:38:12 +03:00
if err != nil {
panic(err)
}
2021-07-17 06:26:40 +03:00
}