mark/markdown/markdown.go

109 lines
3.6 KiB
Go
Raw Normal View History

2019-04-14 13:53:44 +03:00
package mark
import (
"bytes"
2019-04-14 13:53:44 +03:00
2024-09-26 15:24:39 +02:00
"github.com/kovetskiy/mark/attachment"
cparser "github.com/kovetskiy/mark/parser"
crenderer "github.com/kovetskiy/mark/renderer"
"github.com/kovetskiy/mark/stdlib"
2020-11-03 17:12:51 +03:00
"github.com/reconquest/pkg/log"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/util"
)
// Renderer renders anchor [Node]s.
2023-09-01 22:59:04 +02:00
type ConfluenceExtension struct {
html.Config
Stdlib *stdlib.Lib
2023-04-26 08:02:35 +02:00
Path string
MermaidProvider string
MermaidScale float64
DropFirstH1 bool
2023-09-06 16:19:09 -07:00
StripNewlines bool
2023-09-01 22:59:04 +02:00
Attachments []attachment.Attachment
}
// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
2023-09-06 16:19:09 -07:00
func NewConfluenceExtension(stdlib *stdlib.Lib, path string, mermaidProvider string, mermaidScale float64, dropFirstH1 bool, stripNewlines bool) *ConfluenceExtension {
2023-09-01 22:59:04 +02:00
return &ConfluenceExtension{
Config: html.NewConfig(),
Stdlib: stdlib,
2023-04-26 08:02:35 +02:00
Path: path,
MermaidProvider: mermaidProvider,
MermaidScale: mermaidScale,
DropFirstH1: dropFirstH1,
2023-09-06 16:19:09 -07:00
StripNewlines: stripNewlines,
2023-09-01 22:59:04 +02:00
Attachments: []attachment.Attachment{},
2023-03-29 15:31:13 +02:00
}
}
2023-09-06 16:19:09 -07:00
func (c *ConfluenceExtension) Attach(a attachment.Attachment) {
c.Attachments = append(c.Attachments, a)
}
2023-09-01 22:59:04 +02:00
func (c *ConfluenceExtension) Extend(m goldmark.Markdown) {
2023-04-26 08:02:35 +02:00
2023-09-01 22:59:04 +02:00
m.Renderer().AddOptions(renderer.WithNodeRenderers(
2023-09-06 16:19:09 -07:00
util.Prioritized(crenderer.NewConfluenceTextRenderer(c.StripNewlines), 100),
2023-09-01 22:59:04 +02:00
util.Prioritized(crenderer.NewConfluenceBlockQuoteRenderer(), 100),
util.Prioritized(crenderer.NewConfluenceCodeBlockRenderer(c.Stdlib, c.Path), 100),
2023-09-06 16:19:09 -07:00
util.Prioritized(crenderer.NewConfluenceFencedCodeBlockRenderer(c.Stdlib, c, c.MermaidProvider, c.MermaidScale), 100),
2023-09-01 22:59:04 +02:00
util.Prioritized(crenderer.NewConfluenceHTMLBlockRenderer(c.Stdlib), 100),
util.Prioritized(crenderer.NewConfluenceHeadingRenderer(c.DropFirstH1), 100),
2023-09-06 16:19:09 -07:00
util.Prioritized(crenderer.NewConfluenceImageRenderer(c.Stdlib, c, c.Path), 100),
2024-07-25 22:24:36 +02:00
util.Prioritized(crenderer.NewConfluenceParagraphRenderer(), 100),
2023-09-01 22:59:04 +02:00
util.Prioritized(crenderer.NewConfluenceLinkRenderer(), 100),
))
2023-05-04 14:53:33 +02:00
2023-09-01 22:59:04 +02:00
m.Parser().AddOptions(parser.WithInlineParsers(
// Must be registered with a higher priority than goldmark's linkParser to make sure goldmark doesn't parse
// the <ac:*/> tags.
util.Prioritized(cparser.NewConfluenceTagParser(), 199),
))
2023-05-04 14:53:33 +02:00
}
2023-09-06 16:19:09 -07:00
func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidProvider string, mermaidScale float64, dropFirstH1 bool, stripNewlines bool) (string, []attachment.Attachment) {
2019-04-20 10:24:30 +03:00
log.Tracef(nil, "rendering markdown:\n%s", string(markdown))
2023-09-06 16:19:09 -07:00
confluenceExtension := NewConfluenceExtension(stdlib, path, mermaidProvider, mermaidScale, dropFirstH1, stripNewlines)
converter := goldmark.New(
goldmark.WithExtensions(
extension.Footnote,
extension.DefinitionList,
2023-10-23 21:03:57 +02:00
extension.NewTable(
extension.WithTableCellAlignMethod(extension.TableCellAlignStyle),
),
2023-09-01 22:59:04 +02:00
confluenceExtension,
2025-04-15 20:33:43 +02:00
extension.GFM,
2019-04-14 13:53:44 +03:00
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithUnsafe(),
2023-10-23 21:03:57 +02:00
html.WithXHTML(),
))
ctx := parser.NewContext(parser.WithIDs(&cparser.ConfluenceIDs{Values: map[string]bool{}}))
var buf bytes.Buffer
err := converter.Convert(markdown, &buf, parser.WithContext(ctx))
if err != nil {
panic(err)
}
2019-04-14 13:53:44 +03:00
html := buf.Bytes()
2019-04-14 13:53:44 +03:00
2019-04-20 10:24:30 +03:00
log.Tracef(nil, "rendered markdown to html:\n%s", string(html))
2023-09-01 22:59:04 +02:00
return string(html), confluenceExtension.Attachments
}