2023-09-01 22:59:04 +02:00
|
|
|
package renderer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
2024-09-26 15:24:39 +02:00
|
|
|
"github.com/kovetskiy/mark/stdlib"
|
2023-09-01 22:59:04 +02:00
|
|
|
|
|
|
|
"github.com/yuin/goldmark/ast"
|
|
|
|
"github.com/yuin/goldmark/renderer"
|
|
|
|
"github.com/yuin/goldmark/renderer/html"
|
|
|
|
"github.com/yuin/goldmark/util"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ConfluenceHTMLBlockRenderer struct {
|
|
|
|
html.Config
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
|
|
|
|
func NewConfluenceHTMLBlockRenderer(stdlib *stdlib.Lib, opts ...html.Option) renderer.NodeRenderer {
|
|
|
|
return &ConfluenceHTMLBlockRenderer{
|
|
|
|
Config: html.NewConfig(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegisterFuncs implements NodeRenderer.RegisterFuncs .
|
|
|
|
func (r *ConfluenceHTMLBlockRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
|
|
|
|
reg.Register(ast.KindHTMLBlock, r.renderHTMLBlock)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ConfluenceHTMLBlockRenderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
|
|
|
if !entering {
|
|
|
|
return r.goldmarkRenderHTMLBlock(w, source, node, entering)
|
|
|
|
}
|
|
|
|
|
|
|
|
n := node.(*ast.HTMLBlock)
|
|
|
|
l := n.Lines().Len()
|
|
|
|
for i := 0; i < l; i++ {
|
|
|
|
line := n.Lines().At(i)
|
|
|
|
|
|
|
|
switch strings.Trim(string(line.Value(source)), "\n") {
|
|
|
|
case "<!-- ac:layout -->":
|
|
|
|
_, _ = w.WriteString("<ac:layout>\n")
|
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout end -->":
|
|
|
|
_, _ = w.WriteString("</ac:layout>\n")
|
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section type:single -->":
|
2023-12-19 12:57:52 +00:00
|
|
|
_, _ = w.WriteString("<ac:layout-section ac:type=\"single\">\n")
|
2023-09-01 22:59:04 +02:00
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section type:two_equal -->":
|
2023-12-19 12:57:52 +00:00
|
|
|
_, _ = w.WriteString("<ac:layout-section ac:type=\"two_equal\">\n")
|
2023-09-01 22:59:04 +02:00
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section type:two_left_sidebar -->":
|
2023-12-19 12:57:52 +00:00
|
|
|
_, _ = w.WriteString("<ac:layout-section ac:type=\"two_left_sidebar\">\n")
|
2023-09-01 22:59:04 +02:00
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section type:two_right_sidebar -->":
|
2023-12-19 12:57:52 +00:00
|
|
|
_, _ = w.WriteString("<ac:layout-section ac:type=\"two_right_sidebar\">\n")
|
2023-09-01 22:59:04 +02:00
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section type:three -->":
|
2023-12-19 12:57:52 +00:00
|
|
|
_, _ = w.WriteString("<ac:layout-section ac:type=\"three\">\n")
|
2023-09-01 22:59:04 +02:00
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section type:three_with_sidebars -->":
|
2023-12-19 12:57:52 +00:00
|
|
|
_, _ = w.WriteString("<ac:layout-section ac:type=\"three_with_sidebars\">\n")
|
2023-09-01 22:59:04 +02:00
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-section end -->":
|
|
|
|
_, _ = w.WriteString("</ac:layout-section>\n")
|
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-cell -->":
|
|
|
|
_, _ = w.WriteString("<ac:layout-cell>\n")
|
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:layout-cell end -->":
|
|
|
|
_, _ = w.WriteString("</ac:layout-cell>\n")
|
|
|
|
return ast.WalkContinue, nil
|
2024-07-18 15:40:16 +02:00
|
|
|
case "<!-- ac:placeholder -->":
|
|
|
|
_, _ = w.WriteString("<ac:placeholder>\n")
|
|
|
|
return ast.WalkContinue, nil
|
|
|
|
case "<!-- ac:placeholder end -->":
|
|
|
|
_, _ = w.WriteString("</ac:placeholder>\n")
|
|
|
|
return ast.WalkContinue, nil
|
2023-09-01 22:59:04 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r.goldmarkRenderHTMLBlock(w, source, node, entering)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ConfluenceHTMLBlockRenderer) goldmarkRenderHTMLBlock(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
|
|
|
n := node.(*ast.HTMLBlock)
|
|
|
|
if entering {
|
|
|
|
if r.Unsafe {
|
|
|
|
l := n.Lines().Len()
|
|
|
|
for i := 0; i < l; i++ {
|
|
|
|
line := n.Lines().At(i)
|
|
|
|
r.Writer.SecureWrite(w, line.Value(source))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_, _ = w.WriteString("<!-- raw HTML omitted -->\n")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if n.HasClosure() {
|
|
|
|
if r.Unsafe {
|
|
|
|
closure := n.ClosureLine
|
|
|
|
r.Writer.SecureWrite(w, closure.Value(source))
|
|
|
|
} else {
|
|
|
|
_, _ = w.WriteString("<!-- raw HTML omitted -->\n")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ast.WalkContinue, nil
|
|
|
|
}
|