Repository: kovetskiy/mark
Pull request #268 (2023-03-29 13:43:26)

Render codeblocks properly
Fixes: https://github.com/kovetskiy/mark/issues/266


Patch:
diff --git a/pkg/mark/markdown.go b/pkg/mark/markdown.go
index 52c8123..335166d 100644
--- a/pkg/mark/markdown.go
+++ b/pkg/mark/markdown.go
@@ -68,7 +68,7 @@ func (r *ConfluenceRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegister
 	// reg.Register(ast.KindHeading, r.renderNode)
 	reg.Register(ast.KindBlockquote, r.renderBlockQuote)
 	reg.Register(ast.KindCodeBlock, r.renderCodeBlock)
-	reg.Register(ast.KindFencedCodeBlock, r.renderCodeBlock)
+	reg.Register(ast.KindFencedCodeBlock, r.renderFencedCodeBlock)
 	// reg.Register(ast.KindHTMLBlock, r.renderNode)
 	// reg.Register(ast.KindList, r.renderNode)
 	// reg.Register(ast.KindListItem, r.renderNode)
@@ -307,9 +307,8 @@ func (r *ConfluenceRenderer) goldmarkRenderLink(w util.BufWriter, source []byte,
 	return ast.WalkContinue, nil
 }
 
-// renderCodeBlock renders a (Fenced)CodeBlock
-func (r *ConfluenceRenderer) renderCodeBlock(writer util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
-
+// renderFencedCodeBlock renders a FencedCodeBlock
+func (r *ConfluenceRenderer) renderFencedCodeBlock(writer util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
 	if !entering {
 		return ast.WalkContinue, nil
 	}
@@ -384,6 +383,53 @@ func (r *ConfluenceRenderer) renderCodeBlock(writer util.BufWriter, source []byt
 	return ast.WalkContinue, nil
 }
 
+// renderCodeBlock renders a CodeBlock
+func (r *ConfluenceRenderer) renderCodeBlock(writer util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
+	if !entering {
+		return ast.WalkContinue, nil
+	}
+	linenumbers := false
+	firstline := 0
+	theme := ""
+	collapse := false
+	lang := ""
+	title := ""
+
+	var lval []byte
+
+	lines := node.Lines().Len()
+	for i := 0; i < lines; i++ {
+		line := node.Lines().At(i)
+		lval = append(lval, line.Value(source)...)
+	}
+	err := r.Stdlib.Templates.ExecuteTemplate(
+		writer,
+		"ac:code",
+		struct {
+			Language    string
+			Collapse    bool
+			Title       string
+			Theme       string
+			Linenumbers bool
+			Firstline   int
+			Text        string
+		}{
+			lang,
+			collapse,
+			title,
+			theme,
+			linenumbers,
+			firstline,
+			strings.TrimSuffix(string(lval), "\n"),
+		},
+	)
+	if err != nil {
+		return ast.WalkStop, err
+	}
+
+	return ast.WalkContinue, nil
+}
+
 // compileMarkdown will replace tags like <ac:rich-tech-body> with escaped
 // equivalent, because goldmark markdown parser replaces that tags with
 // <a href="ac:rich-text-body">ac:rich-text-body</a> because of the autolink


Test patch:
diff --git a/pkg/mark/testdata/codes.html b/pkg/mark/testdata/codes.html
index c3d724d..163f71c 100644
--- a/pkg/mark/testdata/codes.html
+++ b/pkg/mark/testdata/codes.html
@@ -44,6 +44,19 @@ text 2</p>
 <ac:parameter ac:name="collapse">true</ac:parameter>
 <ac:plain-text-body><![CDATA[collapse-no-title]]></ac:plain-text-body>
 </ac:structured-macro>
+<ac:structured-macro ac:name="code">
+<ac:parameter ac:name="language">nested</ac:parameter>
+<ac:parameter ac:name="collapse">false</ac:parameter>
+<ac:plain-text-body><![CDATA[code
+``` more code ```
+even more code]]></ac:plain-text-body>
+</ac:structured-macro>
+<ac:structured-macro ac:name="code">
+<ac:parameter ac:name="language"></ac:parameter>
+<ac:parameter ac:name="collapse">false</ac:parameter>
+<ac:plain-text-body><![CDATA[indented code block
+with multiple lines]]></ac:plain-text-body>
+</ac:structured-macro>
 <ac:structured-macro ac:name="cloudscript-confluence-mermaid">
 <ac:parameter ac:name="showSource">true</ac:parameter>
 <ac:parameter ac:name="collapse">false</ac:parameter>
diff --git a/pkg/mark/testdata/codes.md b/pkg/mark/testdata/codes.md
index f0a91f9..951f7e1 100644
--- a/pkg/mark/testdata/codes.md
+++ b/pkg/mark/testdata/codes.md
@@ -33,6 +33,15 @@ collapse-and-title
 collapse-no-title
 ```
 
+```nested
+code
+``` more code ```
+even more code
+```
+
+    indented code block
+    with multiple lines
+
 ```mermaid
 graph TD;
     A-->B;