1
0
Fork 0
mirror of https://github.com/diamondburned/cchat-discord.git synced 2024-11-01 12:24:15 +00:00
cchat-discord/internal/segments/link/link.go

81 lines
1.6 KiB
Go

package link
import (
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
"github.com/diamondburned/cchat/text"
"github.com/diamondburned/cchat/utils/empty"
"github.com/yuin/goldmark/ast"
)
func init() {
renderer.Register(ast.KindLink, link)
renderer.Register(ast.KindAutoLink, autoLink)
}
func link(r *renderer.Text, node ast.Node, enter bool) ast.WalkStatus {
n := node.(*ast.Link)
// If we're entering the link node, then add the starting point to the stack
// and move on.
if enter {
r.Links.Append(r.Buffer.Len())
return ast.WalkContinue
}
// If there's nothing in the stack, then don't do anything. This shouldn't
// happen.
if r.Links.Len() == 0 {
return ast.WalkContinue
}
// We're exiting the link node. Pop the segment off the stack.
start := r.Links.Pop()
// Close the segment on enter false.
r.Append(NewSegment(start, r.Buffer.Len(), string(n.Destination)))
return ast.WalkContinue
}
func autoLink(r *renderer.Text, node ast.Node, enter bool) ast.WalkStatus {
n := node.(*ast.AutoLink)
if enter {
start, end := r.Write(n.URL(r.Source))
r.Append(NewSegment(start, end, string(n.URL(r.Source))))
}
return ast.WalkContinue
}
type URL string
var _ text.Linker = (*URL)(nil)
func (u URL) Link() string { return string(u) }
type Segment struct {
empty.TextSegment
start int
end int
url URL
}
var _ text.Segment = (*Segment)(nil)
func NewSegment(start, end int, url string) Segment {
return Segment{
start: start,
end: end,
url: URL(url),
}
}
func (l Segment) Bounds() (start, end int) {
return l.start, l.end
}
func (l Segment) AsLinker() text.Linker {
return l.url
}