markdown.go

  1// Package goldmark implements functions to convert markdown text to a desired format.
  2package goldmark
  3
  4import (
  5	"io"
  6
  7	"github.com/yuin/goldmark/parser"
  8	"github.com/yuin/goldmark/renderer"
  9	"github.com/yuin/goldmark/renderer/html"
 10	"github.com/yuin/goldmark/text"
 11	"github.com/yuin/goldmark/util"
 12)
 13
 14// DefaultParser returns a new Parser that is configured by default values.
 15func DefaultParser() parser.Parser {
 16	return parser.NewParser(parser.WithBlockParsers(parser.DefaultBlockParsers()...),
 17		parser.WithInlineParsers(parser.DefaultInlineParsers()...),
 18		parser.WithParagraphTransformers(parser.DefaultParagraphTransformers()...),
 19	)
 20}
 21
 22// DefaultRenderer returns a new Renderer that is configured by default values.
 23func DefaultRenderer() renderer.Renderer {
 24	return renderer.NewRenderer(renderer.WithNodeRenderers(util.Prioritized(html.NewRenderer(), 1000)))
 25}
 26
 27var defaultMarkdown = New()
 28
 29// Convert interprets a UTF-8 bytes source in Markdown and
 30// write rendered contents to a writer w.
 31func Convert(source []byte, w io.Writer, opts ...parser.ParseOption) error {
 32	return defaultMarkdown.Convert(source, w, opts...)
 33}
 34
 35// A Markdown interface offers functions to convert Markdown text to
 36// a desired format.
 37type Markdown interface {
 38	// Convert interprets a UTF-8 bytes source in Markdown and write rendered
 39	// contents to a writer w.
 40	Convert(source []byte, writer io.Writer, opts ...parser.ParseOption) error
 41
 42	// Parser returns a Parser that will be used for conversion.
 43	Parser() parser.Parser
 44
 45	// SetParser sets a Parser to this object.
 46	SetParser(parser.Parser)
 47
 48	// Parser returns a Renderer that will be used for conversion.
 49	Renderer() renderer.Renderer
 50
 51	// SetRenderer sets a Renderer to this object.
 52	SetRenderer(renderer.Renderer)
 53}
 54
 55// Option is a functional option type for Markdown objects.
 56type Option func(*markdown)
 57
 58// WithExtensions adds extensions.
 59func WithExtensions(ext ...Extender) Option {
 60	return func(m *markdown) {
 61		m.extensions = append(m.extensions, ext...)
 62	}
 63}
 64
 65// WithParser allows you to override the default parser.
 66func WithParser(p parser.Parser) Option {
 67	return func(m *markdown) {
 68		m.parser = p
 69	}
 70}
 71
 72// WithParserOptions applies options for the parser.
 73func WithParserOptions(opts ...parser.Option) Option {
 74	return func(m *markdown) {
 75		m.parser.AddOptions(opts...)
 76	}
 77}
 78
 79// WithRenderer allows you to override the default renderer.
 80func WithRenderer(r renderer.Renderer) Option {
 81	return func(m *markdown) {
 82		m.renderer = r
 83	}
 84}
 85
 86// WithRendererOptions applies options for the renderer.
 87func WithRendererOptions(opts ...renderer.Option) Option {
 88	return func(m *markdown) {
 89		m.renderer.AddOptions(opts...)
 90	}
 91}
 92
 93type markdown struct {
 94	parser     parser.Parser
 95	renderer   renderer.Renderer
 96	extensions []Extender
 97}
 98
 99// New returns a new Markdown with given options.
100func New(options ...Option) Markdown {
101	md := &markdown{
102		parser:     DefaultParser(),
103		renderer:   DefaultRenderer(),
104		extensions: []Extender{},
105	}
106	for _, opt := range options {
107		opt(md)
108	}
109	for _, e := range md.extensions {
110		e.Extend(md)
111	}
112	return md
113}
114
115func (m *markdown) Convert(source []byte, writer io.Writer, opts ...parser.ParseOption) error {
116	reader := text.NewReader(source)
117	doc := m.parser.Parse(reader, opts...)
118	return m.renderer.Render(writer, source, doc)
119}
120
121func (m *markdown) Parser() parser.Parser {
122	return m.parser
123}
124
125func (m *markdown) SetParser(v parser.Parser) {
126	m.parser = v
127}
128
129func (m *markdown) Renderer() renderer.Renderer {
130	return m.renderer
131}
132
133func (m *markdown) SetRenderer(v renderer.Renderer) {
134	m.renderer = v
135}
136
137// An Extender interface is used for extending Markdown.
138type Extender interface {
139	// Extend extends the Markdown.
140	Extend(Markdown)
141}