/
pagecontentoutput.go
118 lines (93 loc) · 2.54 KB
/
pagecontentoutput.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package entity
import (
"context"
"fmt"
"github.com/dddplayer/hugoverse/internal/domain/contentspec"
"github.com/dddplayer/hugoverse/internal/domain/hugosites/valueobject"
"github.com/dddplayer/hugoverse/pkg/lazy"
"html/template"
"runtime/debug"
"strings"
"sync"
"time"
)
func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, error) {
parent := p.init
cp := &pageContentOutput{
p: p,
f: po.f,
}
initContent := func() (err error) {
if p.cmap == nil {
// Nothing to do.
return nil
}
defer func() {
// See https://github.com/gohugoio/hugo/issues/6210
if r := recover(); r != nil {
err = fmt.Errorf("%s", r)
fmt.Printf("[BUG] Got panic:\n%s\n%s", r, string(debug.Stack()))
}
}()
cp.workContent = p.contentToRender(p.source.parsed, p.cmap)
r, err := cp.renderContent(cp.workContent, true)
if err != nil {
return err
}
cp.workContent = r.Bytes()
cp.content = BytesToHTML(cp.workContent)
return nil
}
// There may be recursive loops in shortcodes and render hooks.
cp.initMain = parent.BranchWithTimeout(30*time.Second, func(ctx context.Context) (any, error) {
return nil, initContent()
})
cp.initPlain = cp.initMain.Branch(func() (any, error) {
cp.plain = string(cp.content)
cp.plainWords = strings.Fields(cp.plain)
return nil, nil
})
return cp, nil
}
// BytesToHTML converts bytes to type template.HTML.
func BytesToHTML(b []byte) template.HTML {
return template.HTML(string(b))
}
// pageContentOutput represents the Page content for a given output format.
type pageContentOutput struct {
f valueobject.Format
p *pageState
// Lazy load dependencies
initMain *lazy.Init
initPlain *lazy.Init
placeholdersEnabled bool
placeholdersEnabledInit sync.Once
workContent []byte
// Content sections
content template.HTML
summary template.HTML
truncated bool
plainWords []string
plain string
fuzzyWordCount int
wordCount int
readingTime int
}
func (cp *pageContentOutput) renderContent(content []byte, renderTOC bool) (contentspec.Result, error) {
c := cp.p.getContentConverter()
return cp.renderContentWithConverter(c, content, renderTOC)
}
func (cp *pageContentOutput) renderContentWithConverter(c contentspec.Converter, content []byte, renderTOC bool) (contentspec.Result, error) {
r, err := c.Convert(
contentspec.RenderContext{
Src: content,
RenderTOC: renderTOC,
})
return r, err
}
func (cp *pageContentOutput) Content() (any, error) {
if cp.p.s.initInit(cp.initMain) {
return cp.content, nil
}
return nil, nil
}