mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-12 05:20:26 +00:00
Auto-detect links
This commit is contained in:
parent
987dc5b20f
commit
bee862563d
@ -1,8 +1,6 @@
|
||||
package hyphae
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/go-memdb"
|
||||
)
|
||||
|
||||
@ -15,8 +13,23 @@ type Hypha struct {
|
||||
BackLinks []string
|
||||
}
|
||||
|
||||
func AddHypha(h Hypha) error {
|
||||
return errors.New("Not implemented")
|
||||
// AddHypha adds a hypha named `name` with such `textPath` and `binaryPath`. Both paths can be empty. Does //not// check for hypha's existence beforehand. Count is handled.
|
||||
func AddHypha(name, textPath, binaryPath string) {
|
||||
txn := db.Txn(true)
|
||||
txn.Insert("hyphae",
|
||||
&Hypha{
|
||||
Name: name,
|
||||
TextPath: textPath,
|
||||
BinaryPath: binaryPath,
|
||||
OutLinks: make([]string, 0),
|
||||
BackLinks: make([]string, 0),
|
||||
})
|
||||
txn.Commit()
|
||||
IncrementCount()
|
||||
}
|
||||
|
||||
// DeleteHypha clears both paths and all out-links from the named hypha and marks it as non-existent. It does not actually delete it from the memdb. Count is handled.
|
||||
func DeleteHypha(name string) {
|
||||
}
|
||||
|
||||
// Create the DB schema
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"html"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type spanTokenType int
|
||||
@ -34,8 +35,10 @@ func tagFromState(stt spanTokenType, tagState map[spanTokenType]bool, tagName, o
|
||||
}
|
||||
}
|
||||
|
||||
func getLinkNode(input *bytes.Buffer, hyphaName string) string {
|
||||
input.Next(2)
|
||||
func getLinkNode(input *bytes.Buffer, hyphaName string, isBracketedLink bool) string {
|
||||
if isBracketedLink {
|
||||
input.Next(2) // drop those [[
|
||||
}
|
||||
var (
|
||||
escaping = false
|
||||
addrBuf = bytes.Buffer{}
|
||||
@ -47,11 +50,13 @@ func getLinkNode(input *bytes.Buffer, hyphaName string) string {
|
||||
if escaping {
|
||||
currBuf.WriteByte(b)
|
||||
escaping = false
|
||||
} else if b == '|' && currBuf == &addrBuf {
|
||||
} else if isBracketedLink && b == '|' && currBuf == &addrBuf {
|
||||
currBuf = &displayBuf
|
||||
} else if b == ']' && bytes.HasPrefix(input.Bytes(), []byte{']'}) {
|
||||
} else if isBracketedLink && b == ']' && bytes.HasPrefix(input.Bytes(), []byte{']'}) {
|
||||
input.Next(1)
|
||||
break
|
||||
} else if !isBracketedLink && unicode.IsSpace(rune(b)) {
|
||||
break
|
||||
} else {
|
||||
currBuf.WriteByte(b)
|
||||
}
|
||||
@ -65,6 +70,12 @@ func getTextNode(input *bytes.Buffer) string {
|
||||
var (
|
||||
textNodeBuffer = bytes.Buffer{}
|
||||
escaping = false
|
||||
startsWith = func(t string) bool {
|
||||
return bytes.HasPrefix(input.Bytes(), []byte(t))
|
||||
}
|
||||
couldBeLinkStart = func() bool {
|
||||
return startsWith("https://") || startsWith("http://") || startsWith("gemini://") || startsWith("gopher://") || startsWith("ftp://")
|
||||
}
|
||||
)
|
||||
// Always read the first byte in advance to avoid endless loops that kill computers (sad experience)
|
||||
if input.Len() != 0 {
|
||||
@ -82,6 +93,9 @@ func getTextNode(input *bytes.Buffer) string {
|
||||
} else if strings.IndexByte("/*`^,![~", b) >= 0 {
|
||||
input.UnreadByte()
|
||||
break
|
||||
} else if couldBeLinkStart() {
|
||||
textNodeBuffer.WriteByte(b)
|
||||
break
|
||||
} else {
|
||||
textNodeBuffer.WriteByte(b)
|
||||
}
|
||||
@ -132,7 +146,9 @@ func ParagraphToHtml(hyphaName, input string) string {
|
||||
ret.WriteString(tagFromState(spanMark, tagState, "s", "~~"))
|
||||
p.Next(2)
|
||||
case startsWith("[["):
|
||||
ret.WriteString(getLinkNode(p, hyphaName))
|
||||
ret.WriteString(getLinkNode(p, hyphaName, true))
|
||||
case startsWith("https://"), startsWith("http://"), startsWith("gemini://"), startsWith("gopher://"), startsWith("ftp://"):
|
||||
ret.WriteString(getLinkNode(p, hyphaName, false))
|
||||
default:
|
||||
ret.WriteString(html.EscapeString(getTextNode(p)))
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ main h1:not(.navi-title) {font-size:1.7rem;}
|
||||
blockquote {border-left: 4px black solid; margin-left: 0; padding-left: 1rem;}
|
||||
.wikilink_new {color:#a55858;}
|
||||
.wikilink_new:visited {color:#a55858;}
|
||||
.wikilink__destination-type {display: inline; margin-left: .5rem; vertical-align: sub; }
|
||||
.wikilink__destination-type {display: inline; margin: 0 .25rem; vertical-align: sub; }
|
||||
|
||||
article code {background-color:#eee; padding: .1rem .3rem; border-radius: .25rem; font-size: 90%; }
|
||||
article pre.codeblock {background-color:#eee; padding:.5rem; white-space: pre-wrap; border-radius: .25rem;}
|
||||
|
@ -20,7 +20,7 @@ main h1:not(.navi-title) {font-size:1.7rem;}
|
||||
blockquote {border-left: 4px black solid; margin-left: 0; padding-left: 1rem;}
|
||||
.wikilink_new {color:#a55858;}
|
||||
.wikilink_new:visited {color:#a55858;}
|
||||
.wikilink__destination-type {display: inline; margin-left: .5rem; vertical-align: sub; }
|
||||
.wikilink__destination-type {display: inline; margin: 0 .25rem; vertical-align: sub; }
|
||||
|
||||
article code {background-color:#eee; padding: .1rem .3rem; border-radius: .25rem; font-size: 90%; }
|
||||
article pre.codeblock {background-color:#eee; padding:.5rem; white-space: pre-wrap; border-radius: .25rem;}
|
||||
|
Loading…
Reference in New Issue
Block a user