diff --git a/assets/assets.qtpl.go b/assets/assets.qtpl.go
index 00ad405..fb79b57 100644
--- a/assets/assets.qtpl.go
+++ b/assets/assets.qtpl.go
@@ -381,8 +381,6 @@ mark { background: rgba(130, 80, 30, 5); color: inherit; }
.hypha-tabs { background-color: #232323; }
}
}
-
-.backlinks { display: none; }
`)
//line assets/assets.qtpl:10
qw422016.N().S(`
diff --git a/assets/default.css b/assets/default.css
index 90d3b5a..8700c5a 100644
--- a/assets/default.css
+++ b/assets/default.css
@@ -270,5 +270,3 @@ mark { background: rgba(130, 80, 30, 5); color: inherit; }
.hypha-tabs { background-color: #232323; }
}
}
-
-.backlinks { display: none; }
diff --git a/hyphae/files.go b/hyphae/files.go
index 05b856d..ad98fd8 100644
--- a/hyphae/files.go
+++ b/hyphae/files.go
@@ -11,8 +11,6 @@ import (
// Index finds all hypha files in the full `path` and saves them to the hypha storage.
func Index(path string) {
- byNamesMutex.Lock()
- defer byNamesMutex.Unlock()
byNames = make(map[string]*Hypha)
ch := make(chan *Hypha, 5)
@@ -23,11 +21,10 @@ func Index(path string) {
for h := range ch {
// At this time it is safe to ignore the mutex, because there is only one worker.
- if oldHypha, ok := byNames[h.Name]; ok {
- oldHypha.MergeIn(h)
+ if oh := ByName(h.Name); oh.Exists {
+ oh.MergeIn(h)
} else {
- byNames[h.Name] = h
- IncrementCount()
+ h.Insert()
}
}
}
diff --git a/hyphae/hyphae.go b/hyphae/hyphae.go
index 59e2763..996b65f 100644
--- a/hyphae/hyphae.go
+++ b/hyphae/hyphae.go
@@ -13,12 +13,10 @@ var HyphaPattern = regexp.MustCompile(`[^?!:#@><*|"\'&%{}]+`)
type Hypha struct {
sync.RWMutex
- Name string
+ Name string // Canonical name
Exists bool
- TextPath string
- BinaryPath string
- OutLinks []*Hypha
- BackLinks []*Hypha
+ TextPath string // == "" => no text part
+ BinaryPath string // == "" => no attachment
}
var byNames = make(map[string]*Hypha)
@@ -31,56 +29,44 @@ func EmptyHypha(hyphaName string) *Hypha {
Exists: false,
TextPath: "",
BinaryPath: "",
- OutLinks: make([]*Hypha, 0),
- BackLinks: make([]*Hypha, 0),
}
}
-// ByName returns a hypha by name. If h.Exists, the returned hypha pointer is known to be part of the hypha index (byNames map).
+// ByName returns a hypha by name. It may have been recorded to the storage.
func ByName(hyphaName string) (h *Hypha) {
- h, exists := byNames[hyphaName]
- if exists {
+ h, recorded := byNames[hyphaName]
+ if recorded {
return h
}
return EmptyHypha(hyphaName)
}
-// Insert inserts the hypha into the storage. It overwrites the previous record, if there was any, and returns false. If the was no previous record, return true.
-func (h *Hypha) Insert() (justCreated bool) {
- hp := ByName(h.Name)
-
+func storeHypha(h *Hypha) {
byNamesMutex.Lock()
- defer byNamesMutex.Unlock()
- if hp.Exists {
- hp = h
+ byNames[h.Name] = h
+ byNamesMutex.Unlock()
+}
+
+// Insert inserts the hypha into the storage. A previous record is used if possible. Count incrementation is done if needed.
+func (h *Hypha) Insert() (justRecorded bool) {
+ hp, recorded := byNames[h.Name]
+ if recorded {
+ hp.MergeIn(h)
} else {
- h.Exists = true
- byNames[h.Name] = h
+ storeHypha(h)
IncrementCount()
}
- return !hp.Exists
+ return !recorded
}
-func (h *Hypha) InsertIfNew() (justCreated bool) {
+func (h *Hypha) InsertIfNew() (justRecorded bool) {
if !h.Exists {
return h.Insert()
}
return false
}
-func (h *Hypha) InsertIfNewKeepExistence() {
- hp := ByName(h.Name)
-
- byNamesMutex.Lock()
- defer byNamesMutex.Unlock()
- if hp.Exists {
- hp = h
- } else {
- byNames[h.Name] = h
- }
-}
-
func (h *Hypha) Delete() {
byNamesMutex.Lock()
h.Lock()
@@ -88,10 +74,6 @@ func (h *Hypha) Delete() {
DecrementCount()
byNamesMutex.Unlock()
h.Unlock()
-
- for _, outlinkHypha := range h.OutLinks {
- outlinkHypha.DropBackLink(h)
- }
}
func (h *Hypha) RenameTo(newName string) {
@@ -106,6 +88,10 @@ func (h *Hypha) RenameTo(newName string) {
// MergeIn merges in content file paths from a different hypha object. Prints warnings sometimes.
func (h *Hypha) MergeIn(oh *Hypha) {
+ if h == oh {
+ return
+ }
+ h.Lock()
if h.TextPath == "" && oh.TextPath != "" {
h.TextPath = oh.TextPath
}
@@ -115,61 +101,6 @@ func (h *Hypha) MergeIn(oh *Hypha) {
}
h.BinaryPath = oh.BinaryPath
}
-}
-
-// ## Link related stuff
-// Notes in pseudocode and whatnot:
-// * (Reader h) does not mutate h => safe
-// * (Rename h) reuses the same hypha object => safe
-// * (Unattach h) and (Attach h) do not change (Backlinks h) => safe
-
-// * (Delete h) does not change (Backlinks h), but changes (Outlinks h), removing h from them => make it safe
-// * (Unattach h) and (Attach h) => h may start or stop existing => may change (Outlinks h) => make it safe
-// * (Edit h) => h may start existing => may change (Backlinks h) => make it safe
-// * (Edit h) may add or remove h to or from (Outlinks h) => make it safe
-
-func (h *Hypha) AddOutLink(oh *Hypha) (added bool) {
- h.Lock()
- defer h.Unlock()
-
- for _, outlink := range h.OutLinks {
- if outlink == oh {
- return false
- }
- }
- h.OutLinks = append(h.OutLinks, oh)
- return true
-}
-
-func (h *Hypha) AddBackLink(bh *Hypha) (added bool) {
- h.Lock()
- defer h.Unlock()
-
- for _, backlink := range h.BackLinks {
- if backlink == h {
- return false
- }
- }
- h.BackLinks = append(h.BackLinks, bh)
- return true
-}
-
-func (h *Hypha) DropBackLink(bh *Hypha) {
- h.Lock()
- defer h.Unlock()
-
- if len(h.BackLinks) <= 1 {
- h.BackLinks = make([]*Hypha, 0)
- return
- }
- lastBackLinkIndex := len(h.BackLinks)
- for i, backlink := range h.BackLinks {
- if backlink == bh {
- if i != lastBackLinkIndex {
- h.BackLinks[i] = h.BackLinks[lastBackLinkIndex]
- }
- h.BackLinks = h.BackLinks[:lastBackLinkIndex]
- return
- }
- }
+ h.Exists = oh.Exists
+ h.Unlock()
}
diff --git a/main.go b/main.go
index 2b0987d..b9ff7d1 100644
--- a/main.go
+++ b/main.go
@@ -176,8 +176,6 @@ func main() {
log.Println("Wiki storage directory is", WikiDir)
hyphae.Index(WikiDir)
log.Println("Indexed", hyphae.Count(), "hyphae")
- shroom.FindAllBacklinks()
- log.Println("Found all backlinks")
history.Start(WikiDir)
shroom.SetHeaderLinks()
diff --git a/markup/outlink.go b/markup/outlink.go
index 0580371..0f4203a 100644
--- a/markup/outlink.go
+++ b/markup/outlink.go
@@ -13,6 +13,7 @@ import (
// * Rocketlinks
// * Transclusion
// * Image galleries
+// Not needed anymore, I guess.
func (md *MycoDoc) OutLinks() chan string {
ch := make(chan string)
if !md.parsedAlready {
diff --git a/shroom/backlink.go b/shroom/backlink.go
deleted file mode 100644
index 860ba56..0000000
--- a/shroom/backlink.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package shroom
-
-import (
- "io/ioutil"
- "log"
-
- "github.com/bouncepaw/mycorrhiza/hyphae"
- "github.com/bouncepaw/mycorrhiza/markup"
-)
-
-// FindAllBacklinks iterates over all hyphae that have text parts, sets their outlinks and then sets backlinks.
-func FindAllBacklinks() {
- for h := range hyphae.FilterTextHyphae(hyphae.YieldExistingHyphae()) {
- findBacklinkWorker(h)
- }
-}
-
-func findBacklinkWorker(h *hyphae.Hypha) {
- var (
- textContents, err = ioutil.ReadFile(h.TextPath)
- )
- if err == nil {
- for outlink := range markup.Doc(h.Name, string(textContents)).OutLinks() {
- outlinkHypha := hyphae.ByName(outlink)
- if outlinkHypha == h {
- break
- }
-
- outlinkHypha.AddBackLink(h)
- outlinkHypha.InsertIfNewKeepExistence()
- h.AddOutLink(outlinkHypha)
- }
- } else {
- log.Println("Error when reading text contents of ā%sā: %s", h.Name, err.Error())
- }
-}
diff --git a/views/hypha.qtpl b/views/hypha.qtpl
index a2d74ba..74d6ae6 100644
--- a/views/hypha.qtpl
+++ b/views/hypha.qtpl
@@ -32,23 +32,6 @@
{% endfunc %}
-{% func BackLinksHTML(h *hyphae.Hypha) %}
-
-{% endfunc %}
-
{% func AttachmentHTML(h *hyphae.Hypha) %}
{% switch filepath.Ext(h.BinaryPath) %}
diff --git a/views/hypha.qtpl.go b/views/hypha.qtpl.go
index 499b9aa..13bcc52 100644
--- a/views/hypha.qtpl.go
+++ b/views/hypha.qtpl.go
@@ -123,175 +123,111 @@ func NaviTitleHTML(h *hyphae.Hypha) string {
}
//line views/hypha.qtpl:35
-func StreamBackLinksHTML(qw422016 *qt422016.Writer, h *hyphae.Hypha) {
+func StreamAttachmentHTML(qw422016 *qt422016.Writer, h *hyphae.Hypha) {
//line views/hypha.qtpl:35
qw422016.N().S(`
-
-`)
-//line views/hypha.qtpl:50
-}
-
-//line views/hypha.qtpl:50
-func WriteBackLinksHTML(qq422016 qtio422016.Writer, h *hyphae.Hypha) {
-//line views/hypha.qtpl:50
- qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/hypha.qtpl:50
- StreamBackLinksHTML(qw422016, h)
-//line views/hypha.qtpl:50
- qt422016.ReleaseWriter(qw422016)
-//line views/hypha.qtpl:50
-}
-
-//line views/hypha.qtpl:50
-func BackLinksHTML(h *hyphae.Hypha) string {
-//line views/hypha.qtpl:50
- qb422016 := qt422016.AcquireByteBuffer()
-//line views/hypha.qtpl:50
- WriteBackLinksHTML(qb422016, h)
-//line views/hypha.qtpl:50
- qs422016 := string(qb422016.B)
-//line views/hypha.qtpl:50
- qt422016.ReleaseByteBuffer(qb422016)
-//line views/hypha.qtpl:50
- return qs422016
-//line views/hypha.qtpl:50
-}
-
-//line views/hypha.qtpl:52
-func StreamAttachmentHTML(qw422016 *qt422016.Writer, h *hyphae.Hypha) {
-//line views/hypha.qtpl:52
- qw422016.N().S(`
`)
-//line views/hypha.qtpl:53
+//line views/hypha.qtpl:36
switch filepath.Ext(h.BinaryPath) {
-//line views/hypha.qtpl:55
+//line views/hypha.qtpl:38
case ".jpg", ".gif", ".png", ".webp", ".svg", ".ico":
-//line views/hypha.qtpl:55
+//line views/hypha.qtpl:38
qw422016.N().S(`
`)
-//line views/hypha.qtpl:60
+//line views/hypha.qtpl:43
case ".ogg", ".webm", ".mp4":
-//line views/hypha.qtpl:60
+//line views/hypha.qtpl:43
qw422016.N().S(`
`)
-//line views/hypha.qtpl:68
+//line views/hypha.qtpl:51
case ".mp3":
-//line views/hypha.qtpl:68
+//line views/hypha.qtpl:51
qw422016.N().S(`
`)
-//line views/hypha.qtpl:76
+//line views/hypha.qtpl:59
default:
-//line views/hypha.qtpl:76
+//line views/hypha.qtpl:59
qw422016.N().S(`
`)
-//line views/hypha.qtpl:80
+//line views/hypha.qtpl:63
}
-//line views/hypha.qtpl:80
+//line views/hypha.qtpl:63
qw422016.N().S(`
`)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
}
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
func WriteAttachmentHTML(qq422016 qtio422016.Writer, h *hyphae.Hypha) {
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
StreamAttachmentHTML(qw422016, h)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
qt422016.ReleaseWriter(qw422016)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
}
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
func AttachmentHTML(h *hyphae.Hypha) string {
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
qb422016 := qt422016.AcquireByteBuffer()
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
WriteAttachmentHTML(qb422016, h)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
qs422016 := string(qb422016.B)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
qt422016.ReleaseByteBuffer(qb422016)
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
return qs422016
-//line views/hypha.qtpl:81
+//line views/hypha.qtpl:64
}
diff --git a/views/readers.qtpl b/views/readers.qtpl
index 08e6eb9..cf7c478 100644
--- a/views/readers.qtpl
+++ b/views/readers.qtpl
@@ -108,7 +108,6 @@ If `contents` == "", a helpful message is shown instead.
{%= SubhyphaeHTML(subhyphae) %}
{%= RelativeHyphaeHTML(relatives) %}
-{%= BackLinksHTML(h) %}
{% endfunc %}
diff --git a/views/readers.qtpl.go b/views/readers.qtpl.go
index f9921e4..ef9c851 100644
--- a/views/readers.qtpl.go
+++ b/views/readers.qtpl.go
@@ -345,110 +345,105 @@ func StreamHyphaHTML(qw422016 *qt422016.Writer, rq *http.Request, h *hyphae.Hyph
StreamRelativeHyphaeHTML(qw422016, relatives)
//line views/readers.qtpl:110
qw422016.N().S(`
-`)
-//line views/readers.qtpl:111
- StreamBackLinksHTML(qw422016, h)
-//line views/readers.qtpl:111
- qw422016.N().S(`
`)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
}
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
func WriteHyphaHTML(qq422016 qtio422016.Writer, rq *http.Request, h *hyphae.Hypha, contents string) {
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
StreamHyphaHTML(qw422016, rq, h, contents)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
qt422016.ReleaseWriter(qw422016)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
}
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
func HyphaHTML(rq *http.Request, h *hyphae.Hypha, contents string) string {
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
qb422016 := qt422016.AcquireByteBuffer()
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
WriteHyphaHTML(qb422016, rq, h, contents)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
qs422016 := string(qb422016.B)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
qt422016.ReleaseByteBuffer(qb422016)
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
return qs422016
-//line views/readers.qtpl:113
+//line views/readers.qtpl:112
}
-//line views/readers.qtpl:115
+//line views/readers.qtpl:114
func StreamRevisionHTML(qw422016 *qt422016.Writer, rq *http.Request, h *hyphae.Hypha, contents, revHash string) {
-//line views/readers.qtpl:115
+//line views/readers.qtpl:114
qw422016.N().S(`
`)
-//line views/readers.qtpl:117
+//line views/readers.qtpl:116
relatives, subhyphae, _, _ := tree.Tree(h.Name)
-//line views/readers.qtpl:118
+//line views/readers.qtpl:117
qw422016.N().S(`
`)
-//line views/readers.qtpl:119
+//line views/readers.qtpl:118
StreamNavHTML(qw422016, rq, h.Name, "revision", revHash)
-//line views/readers.qtpl:119
+//line views/readers.qtpl:118
qw422016.N().S(`
Please note that viewing binary parts of hyphae is not supported in history for now.
`)
-//line views/readers.qtpl:124
+//line views/readers.qtpl:123
qw422016.N().S(NaviTitleHTML(h))
-//line views/readers.qtpl:124
+//line views/readers.qtpl:123
qw422016.N().S(`
`)
-//line views/readers.qtpl:125
+//line views/readers.qtpl:124
qw422016.N().S(contents)
-//line views/readers.qtpl:125
+//line views/readers.qtpl:124
qw422016.N().S(`
`)
-//line views/readers.qtpl:127
+//line views/readers.qtpl:126
StreamSubhyphaeHTML(qw422016, subhyphae)
-//line views/readers.qtpl:127
+//line views/readers.qtpl:126
qw422016.N().S(`
`)
-//line views/readers.qtpl:129
+//line views/readers.qtpl:128
StreamRelativeHyphaeHTML(qw422016, relatives)
-//line views/readers.qtpl:129
+//line views/readers.qtpl:128
qw422016.N().S(`
`)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
}
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
func WriteRevisionHTML(qq422016 qtio422016.Writer, rq *http.Request, h *hyphae.Hypha, contents, revHash string) {
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
StreamRevisionHTML(qw422016, rq, h, contents, revHash)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
qt422016.ReleaseWriter(qw422016)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
}
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
func RevisionHTML(rq *http.Request, h *hyphae.Hypha, contents, revHash string) string {
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
qb422016 := qt422016.AcquireByteBuffer()
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
WriteRevisionHTML(qb422016, rq, h, contents, revHash)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
qs422016 := string(qb422016.B)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
qt422016.ReleaseByteBuffer(qb422016)
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
return qs422016
-//line views/readers.qtpl:131
+//line views/readers.qtpl:130
}