170 lines
4.4 KiB
Go
170 lines
4.4 KiB
Go
package parsing
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/yuin/goldmark/parser"
|
|
"github.com/yuin/goldmark/renderer/html"
|
|
|
|
"github.com/yuin/goldmark"
|
|
highlighting "github.com/yuin/goldmark-highlighting"
|
|
"github.com/yuin/goldmark/extension"
|
|
"github.com/yuin/goldmark/util"
|
|
)
|
|
|
|
// Used for rendering real-time previews of post content.
|
|
var ForumPreviewMarkdown = makeGoldmark(
|
|
false,
|
|
goldmark.WithExtensions(makeGoldmarkExtensions(MarkdownOptions{
|
|
Previews: true,
|
|
Embeds: true,
|
|
})...),
|
|
)
|
|
|
|
// Used for generating the final HTML for a post.
|
|
var ForumRealMarkdown = makeGoldmark(
|
|
false,
|
|
goldmark.WithExtensions(makeGoldmarkExtensions(MarkdownOptions{
|
|
Previews: false,
|
|
Embeds: true,
|
|
})...),
|
|
)
|
|
|
|
// Used for generating plain-text previews of posts.
|
|
var PlaintextMarkdown = makeGoldmark(
|
|
false,
|
|
goldmark.WithExtensions(makeGoldmarkExtensions(MarkdownOptions{
|
|
Previews: false,
|
|
Embeds: true,
|
|
})...),
|
|
goldmark.WithRenderer(plaintextRenderer{}),
|
|
)
|
|
|
|
// Used for processing Discord messages
|
|
var DiscordMarkdown = makeGoldmark(
|
|
false,
|
|
goldmark.WithExtensions(makeGoldmarkExtensions(MarkdownOptions{
|
|
Previews: false,
|
|
Embeds: false,
|
|
})...),
|
|
goldmark.WithRendererOptions(html.WithHardWraps()),
|
|
)
|
|
|
|
// Used for rendering real-time previews of post content.
|
|
var EducationPreviewMarkdown = makeGoldmark(
|
|
true,
|
|
goldmark.WithExtensions(makeGoldmarkExtensions(MarkdownOptions{
|
|
Previews: true,
|
|
Embeds: true,
|
|
Education: true,
|
|
})...),
|
|
goldmark.WithRendererOptions(html.WithUnsafe()),
|
|
)
|
|
|
|
// Used for generating the final HTML for a post.
|
|
var EducationRealMarkdown = makeGoldmark(
|
|
true,
|
|
goldmark.WithExtensions(makeGoldmarkExtensions(MarkdownOptions{
|
|
Previews: false,
|
|
Embeds: true,
|
|
Education: true,
|
|
})...),
|
|
goldmark.WithRendererOptions(html.WithUnsafe()),
|
|
)
|
|
|
|
func ParseMarkdown(source string, md goldmark.Markdown) string {
|
|
var buf bytes.Buffer
|
|
if err := md.Convert([]byte(source), &buf); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return buf.String()
|
|
}
|
|
|
|
type MarkdownOptions struct {
|
|
Previews bool
|
|
Embeds bool
|
|
Education bool
|
|
}
|
|
|
|
func makeGoldmark(rawHTML bool, opts ...goldmark.Option) goldmark.Markdown {
|
|
// We need to re-create Goldmark's default parsers to disable HTML parsing.
|
|
// Or enable it again. yay
|
|
|
|
// See parser.DefaultBlockParsers
|
|
blockParsers := []util.PrioritizedValue{
|
|
util.Prioritized(parser.NewSetextHeadingParser(), 100),
|
|
util.Prioritized(parser.NewThematicBreakParser(), 200),
|
|
util.Prioritized(parser.NewListParser(), 300),
|
|
util.Prioritized(parser.NewListItemParser(), 400),
|
|
util.Prioritized(parser.NewCodeBlockParser(), 500),
|
|
util.Prioritized(parser.NewATXHeadingParser(), 600),
|
|
util.Prioritized(parser.NewFencedCodeBlockParser(), 700),
|
|
util.Prioritized(parser.NewBlockquoteParser(), 800),
|
|
//util.Prioritized(parser.NewHTMLBlockParser(), 900),
|
|
util.Prioritized(parser.NewParagraphParser(), 1000),
|
|
}
|
|
|
|
// See parser.DefaultInlineParsers
|
|
inlineParsers := []util.PrioritizedValue{
|
|
util.Prioritized(parser.NewCodeSpanParser(), 100),
|
|
util.Prioritized(parser.NewLinkParser(), 200),
|
|
util.Prioritized(parser.NewAutoLinkParser(), 300),
|
|
// util.Prioritized(parser.NewRawHTMLParser(), 400),
|
|
util.Prioritized(parser.NewEmphasisParser(), 500),
|
|
}
|
|
|
|
if rawHTML {
|
|
blockParsers = append(blockParsers, util.Prioritized(parser.NewHTMLBlockParser(), 900))
|
|
inlineParsers = append(inlineParsers, util.Prioritized(parser.NewRawHTMLParser(), 400))
|
|
}
|
|
|
|
opts = append(opts, goldmark.WithParser(parser.NewParser(
|
|
parser.WithBlockParsers(blockParsers...),
|
|
parser.WithInlineParsers(inlineParsers...),
|
|
parser.WithParagraphTransformers(parser.DefaultParagraphTransformers()...),
|
|
)))
|
|
|
|
return goldmark.New(opts...)
|
|
}
|
|
|
|
func makeGoldmarkExtensions(opts MarkdownOptions) []goldmark.Extender {
|
|
var extenders []goldmark.Extender
|
|
extenders = append(extenders,
|
|
extension.GFM,
|
|
highlightExtension,
|
|
SpoilerExtension{},
|
|
)
|
|
|
|
if opts.Embeds {
|
|
extenders = append(extenders,
|
|
EmbedExtension{
|
|
Preview: opts.Previews,
|
|
},
|
|
)
|
|
}
|
|
|
|
extenders = append(extenders,
|
|
MathjaxExtension{},
|
|
BBCodeExtension{
|
|
Preview: opts.Previews,
|
|
},
|
|
ggcodeExtension{
|
|
Opts: opts,
|
|
},
|
|
)
|
|
|
|
return extenders
|
|
}
|
|
|
|
var highlightExtension = highlighting.NewHighlighting(
|
|
highlighting.WithFormatOptions(HMNChromaOptions...),
|
|
highlighting.WithWrapperRenderer(func(w util.BufWriter, context highlighting.CodeBlockContext, entering bool) {
|
|
if entering {
|
|
w.WriteString(`<pre class="hmn-code">`)
|
|
} else {
|
|
w.WriteString(`</pre>`)
|
|
}
|
|
}),
|
|
)
|