You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.6 KiB

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