mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-29 09:31:11 -05:00
27757714d0
* Move to goldmark Markdown rendering moved from blackfriday to the goldmark. Multiple subtle changes required to the goldmark extensions to keep current rendering and defaults. Can go further with goldmark linkify and have this work within markdown rendering making the link processor unnecessary. Need to think about how to go about allowing extensions - at present it seems that these would be hard to do without recompilation. * linter fixes Co-authored-by: Lauris BH <lauris@nix.lv>
140 lines
3.6 KiB
Go
140 lines
3.6 KiB
Go
// Package goldmark implements functions to convert markdown text to a desired format.
|
|
package goldmark
|
|
|
|
import (
|
|
"github.com/yuin/goldmark/parser"
|
|
"github.com/yuin/goldmark/renderer"
|
|
"github.com/yuin/goldmark/renderer/html"
|
|
"github.com/yuin/goldmark/text"
|
|
"github.com/yuin/goldmark/util"
|
|
"io"
|
|
)
|
|
|
|
// DefaultParser returns a new Parser that is configured by default values.
|
|
func DefaultParser() parser.Parser {
|
|
return parser.NewParser(parser.WithBlockParsers(parser.DefaultBlockParsers()...),
|
|
parser.WithInlineParsers(parser.DefaultInlineParsers()...),
|
|
parser.WithParagraphTransformers(parser.DefaultParagraphTransformers()...),
|
|
)
|
|
}
|
|
|
|
// DefaultRenderer returns a new Renderer that is configured by default values.
|
|
func DefaultRenderer() renderer.Renderer {
|
|
return renderer.NewRenderer(renderer.WithNodeRenderers(util.Prioritized(html.NewRenderer(), 1000)))
|
|
}
|
|
|
|
var defaultMarkdown = New()
|
|
|
|
// Convert interprets a UTF-8 bytes source in Markdown and
|
|
// write rendered contents to a writer w.
|
|
func Convert(source []byte, w io.Writer, opts ...parser.ParseOption) error {
|
|
return defaultMarkdown.Convert(source, w, opts...)
|
|
}
|
|
|
|
// A Markdown interface offers functions to convert Markdown text to
|
|
// a desired format.
|
|
type Markdown interface {
|
|
// Convert interprets a UTF-8 bytes source in Markdown and write rendered
|
|
// contents to a writer w.
|
|
Convert(source []byte, writer io.Writer, opts ...parser.ParseOption) error
|
|
|
|
// Parser returns a Parser that will be used for conversion.
|
|
Parser() parser.Parser
|
|
|
|
// SetParser sets a Parser to this object.
|
|
SetParser(parser.Parser)
|
|
|
|
// Parser returns a Renderer that will be used for conversion.
|
|
Renderer() renderer.Renderer
|
|
|
|
// SetRenderer sets a Renderer to this object.
|
|
SetRenderer(renderer.Renderer)
|
|
}
|
|
|
|
// Option is a functional option type for Markdown objects.
|
|
type Option func(*markdown)
|
|
|
|
// WithExtensions adds extensions.
|
|
func WithExtensions(ext ...Extender) Option {
|
|
return func(m *markdown) {
|
|
m.extensions = append(m.extensions, ext...)
|
|
}
|
|
}
|
|
|
|
// WithParser allows you to override the default parser.
|
|
func WithParser(p parser.Parser) Option {
|
|
return func(m *markdown) {
|
|
m.parser = p
|
|
}
|
|
}
|
|
|
|
// WithParserOptions applies options for the parser.
|
|
func WithParserOptions(opts ...parser.Option) Option {
|
|
return func(m *markdown) {
|
|
m.parser.AddOptions(opts...)
|
|
}
|
|
}
|
|
|
|
// WithRenderer allows you to override the default renderer.
|
|
func WithRenderer(r renderer.Renderer) Option {
|
|
return func(m *markdown) {
|
|
m.renderer = r
|
|
}
|
|
}
|
|
|
|
// WithRendererOptions applies options for the renderer.
|
|
func WithRendererOptions(opts ...renderer.Option) Option {
|
|
return func(m *markdown) {
|
|
m.renderer.AddOptions(opts...)
|
|
}
|
|
}
|
|
|
|
type markdown struct {
|
|
parser parser.Parser
|
|
renderer renderer.Renderer
|
|
extensions []Extender
|
|
}
|
|
|
|
// New returns a new Markdown with given options.
|
|
func New(options ...Option) Markdown {
|
|
md := &markdown{
|
|
parser: DefaultParser(),
|
|
renderer: DefaultRenderer(),
|
|
extensions: []Extender{},
|
|
}
|
|
for _, opt := range options {
|
|
opt(md)
|
|
}
|
|
for _, e := range md.extensions {
|
|
e.Extend(md)
|
|
}
|
|
return md
|
|
}
|
|
|
|
func (m *markdown) Convert(source []byte, writer io.Writer, opts ...parser.ParseOption) error {
|
|
reader := text.NewReader(source)
|
|
doc := m.parser.Parse(reader, opts...)
|
|
return m.renderer.Render(writer, source, doc)
|
|
}
|
|
|
|
func (m *markdown) Parser() parser.Parser {
|
|
return m.parser
|
|
}
|
|
|
|
func (m *markdown) SetParser(v parser.Parser) {
|
|
m.parser = v
|
|
}
|
|
|
|
func (m *markdown) Renderer() renderer.Renderer {
|
|
return m.renderer
|
|
}
|
|
|
|
func (m *markdown) SetRenderer(v renderer.Renderer) {
|
|
m.renderer = v
|
|
}
|
|
|
|
// An Extender interface is used for extending Markdown.
|
|
type Extender interface {
|
|
// Extend extends the Markdown.
|
|
Extend(Markdown)
|
|
}
|