49 lines
1.5 KiB
Go
49 lines
1.5 KiB
Go
package site
|
|
|
|
import (
|
|
"html"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/yuin/goldmark"
|
|
"github.com/yuin/goldmark/ast"
|
|
"github.com/yuin/goldmark/extension"
|
|
"github.com/yuin/goldmark/text"
|
|
)
|
|
|
|
func (b *builder) searchEntry(e *Entry, url string) searchItem {
|
|
return searchItem{Title: e.Title, Aliases: slices.Concat(e.Keys, e.SearchNames), URL: url,
|
|
Summary: plainMD(e.Summary), Text: searchProse(e.Body), Kind: e.Kind, Label: b.tr(kindName(e)),
|
|
ID: e.ID, Icon: b.entryIcon(e), Version: b.docsVersion(), BuildID: b.buildID}
|
|
}
|
|
|
|
// Index explanations and headings, never scene dumps or executable examples.
|
|
// Link labels and inline identifiers remain useful; destinations and raw HTML
|
|
// are not article text and must not become accidental search keywords.
|
|
func searchProse(markdown string) string {
|
|
source := []byte(markdown)
|
|
doc := goldmark.New(goldmark.WithExtensions(extension.GFM)).Parser().Parse(text.NewReader(source))
|
|
var out strings.Builder
|
|
ast.Walk(doc, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
|
|
if !entering {
|
|
if n.Type() == ast.TypeBlock {
|
|
out.WriteByte(' ')
|
|
}
|
|
return ast.WalkContinue, nil
|
|
}
|
|
switch x := n.(type) {
|
|
case *ast.CodeBlock, *ast.FencedCodeBlock, *ast.HTMLBlock, *ast.RawHTML, *ast.Image:
|
|
return ast.WalkSkipChildren, nil
|
|
case *ast.Text:
|
|
out.Write(x.Segment.Value(source))
|
|
if x.SoftLineBreak() || x.HardLineBreak() {
|
|
out.WriteByte(' ')
|
|
}
|
|
case *ast.String:
|
|
out.Write(x.Value)
|
|
}
|
|
return ast.WalkContinue, nil
|
|
})
|
|
return strings.Join(strings.Fields(html.UnescapeString(out.String())), " ")
|
|
}
|