gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

markdown.go (3728B)


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