diff --git a/hyphae/backlinks/backlinks.go b/hyphae/backlinks/backlinks.go
index 444f373..f56dfee 100644
--- a/hyphae/backlinks/backlinks.go
+++ b/hyphae/backlinks/backlinks.go
@@ -2,16 +2,64 @@
package backlinks
import (
- "github.com/bouncepaw/mycorrhiza/hyphae"
- "github.com/bouncepaw/mycorrhiza/util"
"os"
- "github.com/bouncepaw/mycomarkup/v3"
- "github.com/bouncepaw/mycomarkup/v3/links"
- "github.com/bouncepaw/mycomarkup/v3/mycocontext"
- "github.com/bouncepaw/mycomarkup/v3/tools"
+ "github.com/bouncepaw/mycorrhiza/hyphae"
+ "github.com/bouncepaw/mycorrhiza/util"
)
+// YieldHyphaBacklinks gets backlinks for the desired hypha, sorts and yields them one by one.
+func YieldHyphaBacklinks(hyphaName string) <-chan string {
+ hyphaName = util.CanonicalName(hyphaName)
+ out := make(chan string)
+ sorted := hyphae.PathographicSort(out)
+ go func() {
+ backlinks, exists := backlinkIndex[hyphaName]
+ if exists {
+ for link := range backlinks {
+ out <- link
+ }
+ }
+ close(out)
+ }()
+ return sorted
+}
+
+var backlinkConveyor = make(chan backlinkIndexOperation) // No need to buffer because these operations are rare.
+
+// RunBacklinksConveyor runs an index operation processing loop. Call it somewhere in main.
+func RunBacklinksConveyor() {
+ // It is supposed to run as a goroutine for all the time. So, don't blame the infinite loop.
+ defer close(backlinkConveyor)
+ for {
+ (<-backlinkConveyor).apply()
+ }
+}
+
+var backlinkIndex = make(map[string]linkSet)
+
+// IndexBacklinks traverses all text hyphae, extracts links from them and forms an initial index. Call it when indexing and reindexing hyphae.
+func IndexBacklinks() {
+ // It is safe to ignore the mutex, because there is only one worker.
+ for h := range hyphae.FilterTextHyphae(hyphae.YieldExistingHyphae()) {
+ foundLinks := extractHyphaLinksFromContent(h.Name, fetchText(h))
+ for _, link := range foundLinks {
+ if _, exists := backlinkIndex[link]; !exists {
+ backlinkIndex[link] = make(linkSet)
+ }
+ backlinkIndex[link][h.Name] = struct{}{}
+ }
+ }
+}
+
+// BacklinksCount returns the amount of backlinks to the hypha.
+func BacklinksCount(h *hyphae.Hypha) int {
+ if _, exists := backlinkIndex[h.Name]; exists {
+ return len(backlinkIndex[h.Name])
+ }
+ return 0
+}
+
// Using set here seems like the most appropriate solution
type linkSet map[string]struct{}
@@ -41,18 +89,18 @@ type backlinkIndexOperation interface {
// backlinkIndexEdit contains data for backlink index update after a hypha edit
type backlinkIndexEdit struct {
- Name string
- OldLinks []string
- NewLinks []string
+ name string
+ oldLinks []string
+ newLinks []string
}
-// Apply changes backlink index respective to the operation data
+// apply changes backlink index respective to the operation data
func (op backlinkIndexEdit) apply() {
- oldLinks := toLinkSet(op.OldLinks)
- newLinks := toLinkSet(op.NewLinks)
+ oldLinks := toLinkSet(op.oldLinks)
+ newLinks := toLinkSet(op.newLinks)
for link := range oldLinks {
if _, exists := newLinks[link]; !exists {
- delete(backlinkIndex[link], op.Name)
+ delete(backlinkIndex[link], op.name)
}
}
for link := range newLinks {
@@ -60,134 +108,39 @@ func (op backlinkIndexEdit) apply() {
if _, exists := backlinkIndex[link]; !exists {
backlinkIndex[link] = make(linkSet)
}
- backlinkIndex[link][op.Name] = struct{}{}
+ backlinkIndex[link][op.name] = struct{}{}
}
}
}
// backlinkIndexDeletion contains data for backlink index update after a hypha deletion
type backlinkIndexDeletion struct {
- Name string
- Links []string
+ name string
+ links []string
}
// apply changes backlink index respective to the operation data
func (op backlinkIndexDeletion) apply() {
- for _, link := range op.Links {
+ for _, link := range op.links {
if lSet, exists := backlinkIndex[link]; exists {
- delete(lSet, op.Name)
+ delete(lSet, op.name)
}
}
}
// backlinkIndexRenaming contains data for backlink index update after a hypha renaming
type backlinkIndexRenaming struct {
- OldName string
- NewName string
- Links []string
+ oldName string
+ newName string
+ links []string
}
// Apply changes backlink index respective to the operation data
func (op backlinkIndexRenaming) apply() {
- for _, link := range op.Links {
+ for _, link := range op.links {
if lSet, exists := backlinkIndex[link]; exists {
- delete(lSet, op.OldName)
- backlinkIndex[link][op.NewName] = struct{}{}
+ delete(lSet, op.oldName)
+ backlinkIndex[link][op.newName] = struct{}{}
}
}
}
-
-var backlinkIndex = make(map[string]linkSet)
-var backlinkConveyor = make(chan backlinkIndexOperation, 64)
-
-// I hope, the buffer size is enough -- chekoopa
-// Do we really need the buffer though? Dunno -- bouncepaw
-
-// IndexBacklinks traverses all text hyphae, extracts links from them and forms an initial index
-func IndexBacklinks() {
- // It is safe to ignore the mutex, because there is only one worker.
- src := hyphae.FilterTextHyphae(hyphae.YieldExistingHyphae())
- for h := range src {
- foundLinks := extractHyphaLinksFromContent(h.Name, fetchText(h))
- for _, link := range foundLinks {
- if _, exists := backlinkIndex[link]; !exists {
- backlinkIndex[link] = make(linkSet)
- }
- backlinkIndex[link][h.Name] = struct{}{}
- }
- }
-}
-
-// RunBacklinksConveyor runs an index operation processing loop
-func RunBacklinksConveyor() {
- // It is supposed to run as a goroutine for all the time. So, don't blame the infinite loop.
- defer close(backlinkConveyor)
- for {
- (<-backlinkConveyor).apply()
- }
-}
-
-// BacklinksCount returns the amount of backlinks to the hypha.
-func BacklinksCount(h *hyphae.Hypha) int {
- if _, exists := backlinkIndex[h.Name]; exists {
- return len(backlinkIndex[h.Name])
- }
- return 0
-}
-
-// BacklinksOnEdit is a creation/editing hook for backlinks index
-func BacklinksOnEdit(h *hyphae.Hypha, oldText string) {
- oldLinks := extractHyphaLinksFromContent(h.Name, oldText)
- newLinks := extractHyphaLinks(h)
- backlinkConveyor <- backlinkIndexEdit{h.Name, oldLinks, newLinks}
-}
-
-// BacklinksOnDelete is a deletion hook for backlinks index
-func BacklinksOnDelete(h *hyphae.Hypha, oldText string) {
- oldLinks := extractHyphaLinksFromContent(h.Name, oldText)
- backlinkConveyor <- backlinkIndexDeletion{h.Name, oldLinks}
-}
-
-// BacklinksOnRename is a renaming hook for backlinks index
-func BacklinksOnRename(h *hyphae.Hypha, oldName string) {
- actualLinks := extractHyphaLinks(h)
- backlinkConveyor <- backlinkIndexRenaming{oldName, h.Name, actualLinks}
-}
-
-// YieldHyphaBacklinks gets backlinks for a desired hypha, sorts and iterates over them
-func YieldHyphaBacklinks(query string) <-chan string {
- hyphaName := util.CanonicalName(query)
- out := make(chan string)
- sorted := hyphae.PathographicSort(out)
- go func() {
- backlinks, exists := backlinkIndex[hyphaName]
- if exists {
- for link := range backlinks {
- out <- link
- }
- }
- close(out)
- }()
- return sorted
-}
-
-// extractHyphaLinks extracts hypha links from a desired hypha
-func extractHyphaLinks(h *hyphae.Hypha) []string {
- return extractHyphaLinksFromContent(h.Name, fetchText(h))
-}
-
-// extractHyphaLinksFromContent extracts local hypha links from the provided text.
-func extractHyphaLinksFromContent(hyphaName string, contents string) []string {
- ctx, _ := mycocontext.ContextFromStringInput(hyphaName, contents)
- linkVisitor, getLinks := tools.LinkVisitor(ctx)
- // Ignore the result of BlockTree because we call it for linkVisitor.
- _ = mycomarkup.BlockTree(ctx, linkVisitor)
- foundLinks := getLinks()
- var result []string
- for _, link := range foundLinks {
- if link.OfKind(links.LinkLocalHypha) {
- result = append(result, link.TargetHypha())
- }
- }
- return result
-}
diff --git a/hyphae/backlinks/hooks.go b/hyphae/backlinks/hooks.go
new file mode 100644
index 0000000..eb3fa77
--- /dev/null
+++ b/hyphae/backlinks/hooks.go
@@ -0,0 +1,49 @@
+package backlinks
+
+import (
+ "github.com/bouncepaw/mycomarkup/v3"
+ "github.com/bouncepaw/mycomarkup/v3/links"
+ "github.com/bouncepaw/mycomarkup/v3/mycocontext"
+ "github.com/bouncepaw/mycomarkup/v3/tools"
+ "github.com/bouncepaw/mycorrhiza/hyphae"
+)
+
+// UpdateBacklinksAfterEdit is a creation/editing hook for backlinks index
+func UpdateBacklinksAfterEdit(h *hyphae.Hypha, oldText string) {
+ oldLinks := extractHyphaLinksFromContent(h.Name, oldText)
+ newLinks := extractHyphaLinks(h)
+ backlinkConveyor <- backlinkIndexEdit{h.Name, oldLinks, newLinks}
+}
+
+// UpdateBacklinksAfterDelete is a deletion hook for backlinks index
+func UpdateBacklinksAfterDelete(h *hyphae.Hypha, oldText string) {
+ oldLinks := extractHyphaLinksFromContent(h.Name, oldText)
+ backlinkConveyor <- backlinkIndexDeletion{h.Name, oldLinks}
+}
+
+// UpdateBacklinksAfterRename is a renaming hook for backlinks index
+func UpdateBacklinksAfterRename(h *hyphae.Hypha, oldName string) {
+ actualLinks := extractHyphaLinks(h)
+ backlinkConveyor <- backlinkIndexRenaming{oldName, h.Name, actualLinks}
+}
+
+// extractHyphaLinks extracts hypha links from a desired hypha
+func extractHyphaLinks(h *hyphae.Hypha) []string {
+ return extractHyphaLinksFromContent(h.Name, fetchText(h))
+}
+
+// extractHyphaLinksFromContent extracts local hypha links from the provided text.
+func extractHyphaLinksFromContent(hyphaName string, contents string) []string {
+ ctx, _ := mycocontext.ContextFromStringInput(hyphaName, contents)
+ linkVisitor, getLinks := tools.LinkVisitor(ctx)
+ // Ignore the result of BlockTree because we call it for linkVisitor.
+ _ = mycomarkup.BlockTree(ctx, linkVisitor)
+ foundLinks := getLinks()
+ var result []string
+ for _, link := range foundLinks {
+ if link.OfKind(links.LinkLocalHypha) {
+ result = append(result, link.TargetHypha())
+ }
+ }
+ return result
+}
diff --git a/shroom/delete.go b/shroom/delete.go
index 017e36f..2f3d5a8 100644
--- a/shroom/delete.go
+++ b/shroom/delete.go
@@ -26,7 +26,7 @@ func DeleteHypha(u *user.User, h *hyphae.Hypha, lc *l18n.Localizer) (hop *histor
WithUser(u).
Apply()
if !hop.HasErrors() {
- backlinks.BacklinksOnDelete(h, originalText)
+ backlinks.UpdateBacklinksAfterDelete(h, originalText)
h.Delete()
}
return hop, ""
diff --git a/shroom/rename.go b/shroom/rename.go
index e812937..3c3d11f 100644
--- a/shroom/rename.go
+++ b/shroom/rename.go
@@ -75,7 +75,7 @@ func RenameHypha(h *hyphae.Hypha, newHypha *hyphae.Hypha, recursive bool, u *use
h.TextPath = replaceName(h.TextPath)
h.BinaryPath = replaceName(h.BinaryPath)
h.Unlock()
- backlinks.BacklinksOnRename(h, oldName)
+ backlinks.UpdateBacklinksAfterRename(h, oldName)
}
}
return hop, ""
diff --git a/shroom/upload.go b/shroom/upload.go
index d9b3f0e..a61002b 100644
--- a/shroom/upload.go
+++ b/shroom/upload.go
@@ -106,7 +106,7 @@ func uploadHelp(h *hyphae.Hypha, hop *history.Op, ext string, data []byte, u *us
}
*originalFullPath = fullPath
if hop.Type == history.TypeEditText {
- backlinks.BacklinksOnEdit(h, originalText)
+ backlinks.UpdateBacklinksAfterEdit(h, originalText)
}
return hop.WithFiles(fullPath).WithUser(u).Apply(), ""
}
diff --git a/views/stuff.qtpl b/views/stuff.qtpl
index b1e2b20..b796711 100644
--- a/views/stuff.qtpl
+++ b/views/stuff.qtpl
@@ -122,17 +122,18 @@ It outputs a poorly formatted JSON, but it works and is valid.
}
{% endfunc %}
-{% func BacklinksHTML(query string, generator func(string) <-chan string, lc *l18n.Localizer) %}
+{% func BacklinksHTML(hyphaName string, generator func(string) <-chan string, lc *l18n.Localizer) %}
- {%s lc.Get("ui.backlinks_query", &l18n.Replacements{"query": query})%}
+ {%s lc.Get("ui.backlinks_query", &l18n.Replacements{"query": hyphaName})%}
{%s lc.Get("ui.backlinks_desc")%}
{% endfunc %}
diff --git a/views/stuff.qtpl.go b/views/stuff.qtpl.go
index 3208475..06cde20 100644
--- a/views/stuff.qtpl.go
+++ b/views/stuff.qtpl.go
@@ -431,14 +431,14 @@ func TitleSearchJSON(query string, generator func(string) <-chan string) string
}
//line views/stuff.qtpl:125
-func StreamBacklinksHTML(qw422016 *qt422016.Writer, query string, generator func(string) <-chan string, lc *l18n.Localizer) {
+func StreamBacklinksHTML(qw422016 *qt422016.Writer, hyphaName string, generator func(string) <-chan string, lc *l18n.Localizer) {
//line views/stuff.qtpl:125
qw422016.N().S(`
`)
//line views/stuff.qtpl:128
- qw422016.E().S(lc.Get("ui.backlinks_query", &l18n.Replacements{"query": query}))
+ qw422016.E().S(lc.Get("ui.backlinks_query", &l18n.Replacements{"query": hyphaName}))
//line views/stuff.qtpl:128
qw422016.N().S(`
`)
@@ -449,7 +449,7 @@ func StreamBacklinksHTML(qw422016 *qt422016.Writer, query string, generator func
`)
//line views/stuff.qtpl:131
- for hyphaName := range generator(query) {
+ for hyphaName := range generator(hyphaName) {
//line views/stuff.qtpl:131
qw422016.N().S(`
@@ -468,298 +468,299 @@ func StreamBacklinksHTML(qw422016 *qt422016.Writer, query string, generator func
}
//line views/stuff.qtpl:135
qw422016.N().S(`
+
`)
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
}
-//line views/stuff.qtpl:138
-func WriteBacklinksHTML(qq422016 qtio422016.Writer, query string, generator func(string) <-chan string, lc *l18n.Localizer) {
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
+func WriteBacklinksHTML(qq422016 qtio422016.Writer, hyphaName string, generator func(string) <-chan string, lc *l18n.Localizer) {
+//line views/stuff.qtpl:139
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:138
- StreamBacklinksHTML(qw422016, query, generator, lc)
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
+ StreamBacklinksHTML(qw422016, hyphaName, generator, lc)
+//line views/stuff.qtpl:139
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
}
-//line views/stuff.qtpl:138
-func BacklinksHTML(query string, generator func(string) <-chan string, lc *l18n.Localizer) string {
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
+func BacklinksHTML(hyphaName string, generator func(string) <-chan string, lc *l18n.Localizer) string {
+//line views/stuff.qtpl:139
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:138
- WriteBacklinksHTML(qb422016, query, generator, lc)
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
+ WriteBacklinksHTML(qb422016, hyphaName, generator, lc)
+//line views/stuff.qtpl:139
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
return qs422016
-//line views/stuff.qtpl:138
+//line views/stuff.qtpl:139
}
-//line views/stuff.qtpl:140
+//line views/stuff.qtpl:141
func StreamHelpHTML(qw422016 *qt422016.Writer, content, lang string, lc *l18n.Localizer) {
-//line views/stuff.qtpl:140
+//line views/stuff.qtpl:141
qw422016.N().S(`
`)
-//line views/stuff.qtpl:144
+//line views/stuff.qtpl:145
qw422016.N().S(content)
-//line views/stuff.qtpl:144
+//line views/stuff.qtpl:145
qw422016.N().S(`
`)
-//line views/stuff.qtpl:147
+//line views/stuff.qtpl:148
qw422016.N().S(helpTopicsHTML(lang, lc))
-//line views/stuff.qtpl:147
+//line views/stuff.qtpl:148
qw422016.N().S(`
`)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
}
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
func WriteHelpHTML(qq422016 qtio422016.Writer, content, lang string, lc *l18n.Localizer) {
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
StreamHelpHTML(qw422016, content, lang, lc)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
}
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
func HelpHTML(content, lang string, lc *l18n.Localizer) string {
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
WriteHelpHTML(qb422016, content, lang, lc)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
return qs422016
-//line views/stuff.qtpl:149
+//line views/stuff.qtpl:150
}
-//line views/stuff.qtpl:151
+//line views/stuff.qtpl:152
func StreamHelpEmptyErrorHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:151
+//line views/stuff.qtpl:152
qw422016.N().S(`
`)
-//line views/stuff.qtpl:152
+//line views/stuff.qtpl:153
qw422016.E().S(lc.Get("help.empty_error_title"))
-//line views/stuff.qtpl:152
+//line views/stuff.qtpl:153
qw422016.N().S(`
`)
-//line views/stuff.qtpl:153
+//line views/stuff.qtpl:154
qw422016.E().S(lc.Get("help.empty_error_line_1"))
-//line views/stuff.qtpl:153
+//line views/stuff.qtpl:154
qw422016.N().S(`
`)
-//line views/stuff.qtpl:154
+//line views/stuff.qtpl:155
qw422016.E().S(lc.Get("help.empty_error_line_2a"))
-//line views/stuff.qtpl:154
+//line views/stuff.qtpl:155
qw422016.N().S(` `)
-//line views/stuff.qtpl:154
+//line views/stuff.qtpl:155
qw422016.E().S(lc.Get("help.empty_error_link"))
-//line views/stuff.qtpl:154
+//line views/stuff.qtpl:155
qw422016.N().S(` `)
-//line views/stuff.qtpl:154
+//line views/stuff.qtpl:155
qw422016.E().S(lc.Get("help.empty_error_line_2b"))
-//line views/stuff.qtpl:154
+//line views/stuff.qtpl:155
qw422016.N().S(`
`)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
}
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
func WriteHelpEmptyErrorHTML(qq422016 qtio422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
StreamHelpEmptyErrorHTML(qw422016, lc)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
}
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
func HelpEmptyErrorHTML(lc *l18n.Localizer) string {
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
WriteHelpEmptyErrorHTML(qb422016, lc)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
return qs422016
-//line views/stuff.qtpl:155
+//line views/stuff.qtpl:156
}
-//line views/stuff.qtpl:157
+//line views/stuff.qtpl:158
func streamhelpTopicsHTML(qw422016 *qt422016.Writer, lang string, lc *l18n.Localizer) {
-//line views/stuff.qtpl:157
+//line views/stuff.qtpl:158
qw422016.N().S(`
`)
-//line views/stuff.qtpl:159
+//line views/stuff.qtpl:160
qw422016.E().S(lc.GetWithLocale(lang, "help.topics"))
-//line views/stuff.qtpl:159
+//line views/stuff.qtpl:160
qw422016.N().S(`
`)
-//line views/stuff.qtpl:161
+//line views/stuff.qtpl:162
qw422016.E().S(lc.GetWithLocale(lang, "help.main"))
-//line views/stuff.qtpl:161
+//line views/stuff.qtpl:162
qw422016.N().S(`
`)
-//line views/stuff.qtpl:162
+//line views/stuff.qtpl:163
qw422016.E().S(lc.GetWithLocale(lang, "help.hypha"))
-//line views/stuff.qtpl:162
+//line views/stuff.qtpl:163
qw422016.N().S(`
`)
-//line views/stuff.qtpl:167
+//line views/stuff.qtpl:168
qw422016.E().S(lc.GetWithLocale(lang, "help.mycomarkup"))
-//line views/stuff.qtpl:167
+//line views/stuff.qtpl:168
qw422016.N().S(`
`)
-//line views/stuff.qtpl:168
+//line views/stuff.qtpl:169
qw422016.E().S(lc.GetWithLocale(lang, "help.interface"))
-//line views/stuff.qtpl:168
+//line views/stuff.qtpl:169
qw422016.N().S(`
`)
-//line views/stuff.qtpl:176
+//line views/stuff.qtpl:177
qw422016.E().S(lc.GetWithLocale(lang, "help.special_pages"))
-//line views/stuff.qtpl:176
+//line views/stuff.qtpl:177
qw422016.N().S(`
`)
-//line views/stuff.qtpl:182
+//line views/stuff.qtpl:183
qw422016.E().S(lc.GetWithLocale(lang, "help.configuration"))
-//line views/stuff.qtpl:182
+//line views/stuff.qtpl:183
qw422016.N().S(`
@@ -767,91 +768,91 @@ func streamhelpTopicsHTML(qw422016 *qt422016.Writer, lang string, lc *l18n.Local
`)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
}
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
func writehelpTopicsHTML(qq422016 qtio422016.Writer, lang string, lc *l18n.Localizer) {
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
streamhelpTopicsHTML(qw422016, lang, lc)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
}
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
func helpTopicsHTML(lang string, lc *l18n.Localizer) string {
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
writehelpTopicsHTML(qb422016, lang, lc)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
return qs422016
-//line views/stuff.qtpl:193
+//line views/stuff.qtpl:194
}
-//line views/stuff.qtpl:195
+//line views/stuff.qtpl:196
func streamhelpTopicBadgeHTML(qw422016 *qt422016.Writer, lang, topic string) {
-//line views/stuff.qtpl:195
+//line views/stuff.qtpl:196
qw422016.N().S(`
?
`)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
}
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
func writehelpTopicBadgeHTML(qq422016 qtio422016.Writer, lang, topic string) {
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
streamhelpTopicBadgeHTML(qw422016, lang, topic)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
}
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
func helpTopicBadgeHTML(lang, topic string) string {
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
writehelpTopicBadgeHTML(qb422016, lang, topic)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
return qs422016
-//line views/stuff.qtpl:197
+//line views/stuff.qtpl:198
}
-//line views/stuff.qtpl:199
+//line views/stuff.qtpl:200
func StreamUserListHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:199
+//line views/stuff.qtpl:200
qw422016.N().S(`
`)
-//line views/stuff.qtpl:202
+//line views/stuff.qtpl:203
qw422016.E().S(lc.Get("ui.users_heading"))
-//line views/stuff.qtpl:202
+//line views/stuff.qtpl:203
qw422016.N().S(`
`)
-//line views/stuff.qtpl:204
+//line views/stuff.qtpl:205
var (
admins = make([]string, 0)
moderators = make([]string, 0)
@@ -871,149 +872,149 @@ func StreamUserListHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
sort.Strings(moderators)
sort.Strings(editors)
-//line views/stuff.qtpl:222
+//line views/stuff.qtpl:223
qw422016.N().S(`
`)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
}
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
func WriteUserListHTML(qq422016 qtio422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
StreamUserListHTML(qw422016, lc)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
}
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
func UserListHTML(lc *l18n.Localizer) string {
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
WriteUserListHTML(qb422016, lc)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
return qs422016
-//line views/stuff.qtpl:243
+//line views/stuff.qtpl:244
}
-//line views/stuff.qtpl:245
+//line views/stuff.qtpl:246
func StreamHyphaListHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:245
+//line views/stuff.qtpl:246
qw422016.N().S(`
`)
-//line views/stuff.qtpl:248
+//line views/stuff.qtpl:249
qw422016.E().S(lc.Get("ui.list_heading"))
-//line views/stuff.qtpl:248
+//line views/stuff.qtpl:249
qw422016.N().S(`
`)
-//line views/stuff.qtpl:249
+//line views/stuff.qtpl:250
qw422016.E().S(lc.GetPlural("ui.list_desc", hyphae.Count()))
-//line views/stuff.qtpl:249
+//line views/stuff.qtpl:250
qw422016.N().S(`
`)
-//line views/stuff.qtpl:252
+//line views/stuff.qtpl:253
hyphaNames := make(chan string)
sortedHypha := hyphae.PathographicSort(hyphaNames)
for hypha := range hyphae.YieldExistingHyphae() {
@@ -1021,252 +1022,252 @@ func StreamHyphaListHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
}
close(hyphaNames)
-//line views/stuff.qtpl:258
+//line views/stuff.qtpl:259
qw422016.N().S(`
`)
-//line views/stuff.qtpl:259
+//line views/stuff.qtpl:260
for hyphaName := range sortedHypha {
-//line views/stuff.qtpl:259
+//line views/stuff.qtpl:260
qw422016.N().S(`
`)
-//line views/stuff.qtpl:260
+//line views/stuff.qtpl:261
hypha := hyphae.ByName(hyphaName)
-//line views/stuff.qtpl:260
+//line views/stuff.qtpl:261
qw422016.N().S(`
`)
-//line views/stuff.qtpl:262
+//line views/stuff.qtpl:263
qw422016.E().S(util.BeautifulName(hypha.Name))
-//line views/stuff.qtpl:262
+//line views/stuff.qtpl:263
qw422016.N().S(`
`)
-//line views/stuff.qtpl:263
+//line views/stuff.qtpl:264
if hypha.BinaryPath != "" {
-//line views/stuff.qtpl:263
+//line views/stuff.qtpl:264
qw422016.N().S(`
`)
-//line views/stuff.qtpl:264
+//line views/stuff.qtpl:265
qw422016.E().S(filepath.Ext(hypha.BinaryPath)[1:])
-//line views/stuff.qtpl:264
+//line views/stuff.qtpl:265
qw422016.N().S(`
`)
-//line views/stuff.qtpl:265
+//line views/stuff.qtpl:266
}
-//line views/stuff.qtpl:265
+//line views/stuff.qtpl:266
qw422016.N().S(`
`)
-//line views/stuff.qtpl:267
+//line views/stuff.qtpl:268
}
-//line views/stuff.qtpl:267
+//line views/stuff.qtpl:268
qw422016.N().S(`
`)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
}
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
func WriteHyphaListHTML(qq422016 qtio422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
StreamHyphaListHTML(qw422016, lc)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
}
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
func HyphaListHTML(lc *l18n.Localizer) string {
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
WriteHyphaListHTML(qb422016, lc)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
return qs422016
-//line views/stuff.qtpl:271
+//line views/stuff.qtpl:272
}
-//line views/stuff.qtpl:273
+//line views/stuff.qtpl:274
func StreamAboutHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:273
+//line views/stuff.qtpl:274
qw422016.N().S(`
`)
-//line views/stuff.qtpl:277
+//line views/stuff.qtpl:278
qw422016.E().S(lc.Get("ui.about_title", &l18n.Replacements{"name": cfg.WikiName}))
-//line views/stuff.qtpl:277
+//line views/stuff.qtpl:278
qw422016.N().S(`
`)
-//line views/stuff.qtpl:279
+//line views/stuff.qtpl:280
qw422016.N().S(lc.Get("ui.about_version", &l18n.Replacements{"pre": "", "post": " "}))
-//line views/stuff.qtpl:279
+//line views/stuff.qtpl:280
qw422016.N().S(` 1.7.0
`)
-//line views/stuff.qtpl:280
+//line views/stuff.qtpl:281
if cfg.UseAuth {
-//line views/stuff.qtpl:280
+//line views/stuff.qtpl:281
qw422016.N().S(` `)
-//line views/stuff.qtpl:281
+//line views/stuff.qtpl:282
qw422016.E().S(lc.Get("ui.about_usercount"))
-//line views/stuff.qtpl:281
+//line views/stuff.qtpl:282
qw422016.N().S(` `)
-//line views/stuff.qtpl:281
+//line views/stuff.qtpl:282
qw422016.N().DUL(user.Count())
-//line views/stuff.qtpl:281
+//line views/stuff.qtpl:282
qw422016.N().S(`
`)
-//line views/stuff.qtpl:282
+//line views/stuff.qtpl:283
qw422016.E().S(lc.Get("ui.about_homepage"))
-//line views/stuff.qtpl:282
+//line views/stuff.qtpl:283
qw422016.N().S(` `)
-//line views/stuff.qtpl:282
+//line views/stuff.qtpl:283
qw422016.E().S(cfg.HomeHypha)
-//line views/stuff.qtpl:282
+//line views/stuff.qtpl:283
qw422016.N().S(`
`)
-//line views/stuff.qtpl:283
+//line views/stuff.qtpl:284
qw422016.E().S(lc.Get("ui.about_admins"))
-//line views/stuff.qtpl:283
+//line views/stuff.qtpl:284
qw422016.N().S(` `)
-//line views/stuff.qtpl:283
+//line views/stuff.qtpl:284
for i, username := range user.ListUsersWithGroup("admin") {
-//line views/stuff.qtpl:284
+//line views/stuff.qtpl:285
if i > 0 {
-//line views/stuff.qtpl:284
+//line views/stuff.qtpl:285
qw422016.N().S(`,
`)
-//line views/stuff.qtpl:285
+//line views/stuff.qtpl:286
}
-//line views/stuff.qtpl:285
+//line views/stuff.qtpl:286
qw422016.N().S(` `)
-//line views/stuff.qtpl:286
+//line views/stuff.qtpl:287
qw422016.E().S(username)
-//line views/stuff.qtpl:286
+//line views/stuff.qtpl:287
qw422016.N().S(` `)
-//line views/stuff.qtpl:286
+//line views/stuff.qtpl:287
}
-//line views/stuff.qtpl:286
+//line views/stuff.qtpl:287
qw422016.N().S(`
`)
-//line views/stuff.qtpl:287
+//line views/stuff.qtpl:288
} else {
-//line views/stuff.qtpl:287
+//line views/stuff.qtpl:288
qw422016.N().S(` `)
-//line views/stuff.qtpl:288
+//line views/stuff.qtpl:289
qw422016.E().S(lc.Get("ui.about_noauth"))
-//line views/stuff.qtpl:288
+//line views/stuff.qtpl:289
qw422016.N().S(`
`)
-//line views/stuff.qtpl:289
+//line views/stuff.qtpl:290
}
-//line views/stuff.qtpl:289
+//line views/stuff.qtpl:290
qw422016.N().S(`
`)
-//line views/stuff.qtpl:291
+//line views/stuff.qtpl:292
qw422016.N().S(lc.Get("ui.about_hyphae", &l18n.Replacements{"link": "/list "}))
-//line views/stuff.qtpl:291
+//line views/stuff.qtpl:292
qw422016.N().S(`
`)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
}
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
func WriteAboutHTML(qq422016 qtio422016.Writer, lc *l18n.Localizer) {
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
StreamAboutHTML(qw422016, lc)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
}
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
func AboutHTML(lc *l18n.Localizer) string {
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
WriteAboutHTML(qb422016, lc)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
return qs422016
-//line views/stuff.qtpl:295
+//line views/stuff.qtpl:296
}
-//line views/stuff.qtpl:297
+//line views/stuff.qtpl:298
func StreamCommonScripts(qw422016 *qt422016.Writer) {
-//line views/stuff.qtpl:297
+//line views/stuff.qtpl:298
qw422016.N().S(`
`)
-//line views/stuff.qtpl:298
+//line views/stuff.qtpl:299
for _, scriptPath := range cfg.CommonScripts {
-//line views/stuff.qtpl:298
+//line views/stuff.qtpl:299
qw422016.N().S(`
`)
-//line views/stuff.qtpl:300
+//line views/stuff.qtpl:301
}
-//line views/stuff.qtpl:300
+//line views/stuff.qtpl:301
qw422016.N().S(`
`)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
}
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
func WriteCommonScripts(qq422016 qtio422016.Writer) {
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
qw422016 := qt422016.AcquireWriter(qq422016)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
StreamCommonScripts(qw422016)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
qt422016.ReleaseWriter(qw422016)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
}
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
func CommonScripts() string {
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
qb422016 := qt422016.AcquireByteBuffer()
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
WriteCommonScripts(qb422016)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
qs422016 := string(qb422016.B)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
qt422016.ReleaseByteBuffer(qb422016)
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
return qs422016
-//line views/stuff.qtpl:301
+//line views/stuff.qtpl:302
}