-
Notifications
You must be signed in to change notification settings - Fork 1
/
title_extractor.go
56 lines (42 loc) · 1.28 KB
/
title_extractor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package markdown
import (
"bytes"
"github.com/yuin/goldmark/ast"
gast "github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
)
// titleParserCtxKey stores title extracted from first header
var titleParserCtxKey = parser.NewContextKey()
const maxTitleLen = 120
type titleExtractorTransformer struct{}
// PagePreviewText contains title of document and beginning of content
type PagePreviewText struct {
Title string
Preview string
}
func (t *titleExtractorTransformer) Transform(n *gast.Document, reader text.Reader, pc parser.Context) {
if _, ok := pc.Get(titleParserCtxKey).(*PagePreviewText); ok {
return
}
pc.Set(titleParserCtxKey, &PagePreviewText{})
_ = ast.Walk(n, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
return ast.WalkContinue, nil
}
buf := &bytes.Buffer{}
dst := pc.Get(titleParserCtxKey).(*PagePreviewText)
if n.Kind() == ast.KindHeading && dst.Title == "" {
extractTextFromNode(n, reader, buf)
dst.Title = buf.String()
}
if n.Kind() == ast.KindParagraph && dst.Preview == "" {
extractTextFromNode(n, reader, buf)
dst.Preview = buf.String()
}
if dst.Title != "" && dst.Preview != "" {
return ast.WalkStop, stopWalkError
}
return ast.WalkContinue, nil
})
}