2019-04-14 13:53:44 +03:00
|
|
|
package mark
|
|
|
|
|
|
|
|
import (
|
2023-03-06 16:23:06 +01:00
|
|
|
"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"
|
2023-03-06 16:23:06 +01:00
|
|
|
"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"
|
2023-01-03 18:53:41 +01:00
|
|
|
)
|
|
|
|
|
2023-03-06 16:23:06 +01:00
|
|
|
// Renderer renders anchor [Node]s.
|
2023-09-01 22:59:04 +02:00
|
|
|
type ConfluenceExtension struct {
|
2023-03-06 16:23:06 +01:00
|
|
|
html.Config
|
2023-04-12 13:43:34 +02:00
|
|
|
Stdlib *stdlib.Lib
|
2023-04-26 08:02:35 +02:00
|
|
|
Path string
|
2023-04-12 13:43:34 +02:00
|
|
|
MermaidProvider string
|
2023-08-30 14:50:53 +02:00
|
|
|
MermaidScale float64
|
2023-05-19 18:47:55 +02:00
|
|
|
DropFirstH1 bool
|
2023-09-06 16:19:09 -07:00
|
|
|
StripNewlines bool
|
2023-09-01 22:59:04 +02:00
|
|
|
Attachments []attachment.Attachment
|
2023-01-04 09:54:15 +01:00
|
|
|
}
|
|
|
|
|
2023-03-06 16:23:06 +01:00
|
|
|
// 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{
|
2023-04-12 13:43:34 +02:00
|
|
|
Config: html.NewConfig(),
|
|
|
|
Stdlib: stdlib,
|
2023-04-26 08:02:35 +02:00
|
|
|
Path: path,
|
2023-04-12 13:43:34 +02:00
|
|
|
MermaidProvider: mermaidProvider,
|
2023-08-30 14:50:53 +02:00
|
|
|
MermaidScale: mermaidScale,
|
2023-05-19 18:47:55 +02:00
|
|
|
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)
|
2023-04-12 13:43:34 +02:00
|
|
|
|
2023-03-06 16:23:06 +01:00
|
|
|
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
|
|
|
),
|
2023-03-06 16:23:06 +01:00
|
|
|
goldmark.WithParserOptions(
|
|
|
|
parser.WithAutoHeadingID(),
|
2021-02-02 17:43:31 +03:00
|
|
|
),
|
2023-03-06 16:23:06 +01:00
|
|
|
goldmark.WithRendererOptions(
|
|
|
|
html.WithUnsafe(),
|
2023-10-23 21:03:57 +02:00
|
|
|
html.WithXHTML(),
|
2023-03-06 16:23:06 +01:00
|
|
|
))
|
|
|
|
|
2024-10-22 10:50:06 +02:00
|
|
|
ctx := parser.NewContext(parser.WithIDs(&cparser.ConfluenceIDs{Values: map[string]bool{}}))
|
|
|
|
|
2023-03-06 16:23:06 +01:00
|
|
|
var buf bytes.Buffer
|
2024-10-22 10:50:06 +02:00
|
|
|
err := converter.Convert(markdown, &buf, parser.WithContext(ctx))
|
2023-03-06 16:23:06 +01:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2019-04-14 13:53:44 +03:00
|
|
|
|
2023-03-31 10:51:50 +02: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
|
2022-01-18 09:05:26 +03:00
|
|
|
}
|