1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 03:36:16 +00:00
mycorrhiza/tree/tree.go
Timur Ismagilov ac4c4d665c Tree: Drop the sibling sidebar
Because of that, I could reimplement the rest of the package tree more straight-forward. Also deleted the package iteration because it is no longer used anywhere.
2022-08-06 13:45:10 +05:00

90 lines
2.6 KiB
Go

package tree
import (
"github.com/bouncepaw/mycorrhiza/hyphae"
"path"
"sort"
"strings"
)
// Tree returns the subhypha matrix as HTML and names of the next and previous hyphae (or empty strings).
func Tree(hyphaName string) (childrenHTML, prev, next string) {
var (
root = child{hyphaName, true, make([]child, 0)}
descendantPrefix = hyphaName + "/"
parent = path.Dir(hyphaName) // Beware, it might be . and whatnot.
slashCount = strings.Count(hyphaName, "/")
)
for h := range hyphae.YieldExistingHyphae() {
name := h.CanonicalName()
if strings.HasPrefix(name, descendantPrefix) {
var subPath = strings.TrimPrefix(name, descendantPrefix)
addHyphaToChild(name, subPath, &root)
// A child is not a sibling, so we skip the rest.
continue
}
// Skipping non-siblings.
if !(path.Dir(name) == parent && slashCount == strings.Count(name, "/")) {
continue
}
if (name < hyphaName) && (name > prev) {
prev = name
} else if (name > hyphaName) && (name < next || next == "") {
next = name
}
}
return subhyphaeMatrix(root.children), prev, next
}
type child struct {
name string
exists bool
children []child
}
func addHyphaToChild(hyphaName, subPath string, child *child) {
// when hyphaName = "root/a/b", subPath = "a/b", and child.name = "root"
// addHyphaToChild("root/a/b", "b", child{"root/a"})
// when hyphaName = "root/a/b", subPath = "b", and child.name = "root/a"
// set .exists=true for "root/a/b", and create it if it isn't there already
var exists = !strings.Contains(subPath, "/")
if exists {
var subchild = findOrCreateSubchild(subPath, child)
subchild.exists = true
} else {
var (
firstSlash = strings.IndexRune(subPath, '/')
firstDir = subPath[:firstSlash]
restOfPath = subPath[firstSlash+1:]
subchild = findOrCreateSubchild(firstDir, child)
)
addHyphaToChild(hyphaName, restOfPath, subchild)
}
}
func findOrCreateSubchild(name string, baseChild *child) *child {
// when name = "a", and baseChild.name = "root"
// if baseChild.children contains "root/a", return it
// else create it and return that
var fullName = baseChild.name + "/" + name
for i := range baseChild.children {
if baseChild.children[i].name == fullName {
return &baseChild.children[i]
}
}
baseChild.children = append(baseChild.children, child{fullName, false, make([]child, 0)})
return &baseChild.children[len(baseChild.children)-1]
}
func subhyphaeMatrix(children []child) (html string) {
sort.Slice(children, func(i, j int) bool {
return children[i].name < children[j].name
})
for _, child := range children {
html += childHTML(&child)
}
return html
}