-
Notifications
You must be signed in to change notification settings - Fork 4
/
client_render.go
82 lines (70 loc) · 2.23 KB
/
client_render.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
package mermaid
import (
"html/template"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/util"
)
const _defaultMermaidJS = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"
// ClientRenderer renders Mermaid diagrams as HTML,
// to be rendered into images client side.
//
// It operates by installing a <script> tag into the document
// that renders the Mermaid diagrams client-side.
type ClientRenderer struct {
// URL of Mermaid Javascript to be included in the page.
//
// Defaults to the latest version available on cdn.jsdelivr.net.
MermaidURL string
// ContainerTag is the name of the HTML tag to use for the container
// that holds the Mermaid diagram.
// The name must be without the angle brackets.
//
// Defaults to "pre".
ContainerTag string
}
// RegisterFuncs registers the renderer for Mermaid blocks with the provided
// Goldmark Registerer.
func (r *ClientRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(Kind, r.Render)
reg.Register(ScriptKind, r.RenderScript)
}
// Render renders mermaid.Block nodes.
func (r *ClientRenderer) Render(w util.BufWriter, src []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
tag := r.ContainerTag
if len(tag) == 0 {
tag = "pre"
}
n := node.(*Block)
if entering {
_, _ = w.WriteString("<")
template.HTMLEscape(w, []byte(tag))
_, _ = w.WriteString(` class="mermaid">`)
lines := n.Lines()
for i := 0; i < lines.Len(); i++ {
line := lines.At(i)
template.HTMLEscape(w, line.Value(src))
}
} else {
_, _ = w.WriteString("</")
template.HTMLEscape(w, []byte(tag))
_, _ = w.WriteString(">")
}
return ast.WalkContinue, nil
}
// RenderScript renders mermaid.ScriptBlock nodes.
func (r *ClientRenderer) RenderScript(w util.BufWriter, _ []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
mermaidJS := r.MermaidURL
if len(mermaidJS) == 0 {
mermaidJS = _defaultMermaidJS
}
_ = node.(*ScriptBlock) // sanity check
if entering {
_, _ = w.WriteString(`<script src="`)
_, _ = w.WriteString(mermaidJS)
_, _ = w.WriteString(`"></script>`)
} else {
_, _ = w.WriteString("<script>mermaid.initialize({startOnLoad: true});</script>")
}
return ast.WalkContinue, nil
}