markdown.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package markdown
  2. import (
  3. "bytes"
  4. "io"
  5. "github.com/gomarkdown/markdown/ast"
  6. "github.com/gomarkdown/markdown/html"
  7. "github.com/gomarkdown/markdown/parser"
  8. )
  9. // Renderer is an interface for implementing custom renderers.
  10. type Renderer interface {
  11. // RenderNode renders markdown node to w.
  12. // It's called once for a leaf node.
  13. // It's called twice for non-leaf nodes:
  14. // * first with entering=true
  15. // * then with entering=false
  16. //
  17. // Return value is a way to tell the calling walker to adjust its walk
  18. // pattern: e.g. it can terminate the traversal by returning Terminate. Or it
  19. // can ask the walker to skip a subtree of this node by returning SkipChildren.
  20. // The typical behavior is to return GoToNext, which asks for the usual
  21. // traversal to the next node.
  22. RenderNode(w io.Writer, node ast.Node, entering bool) ast.WalkStatus
  23. // RenderHeader is a method that allows the renderer to produce some
  24. // content preceding the main body of the output document. The header is
  25. // understood in the broad sense here. For example, the default HTML
  26. // renderer will write not only the HTML document preamble, but also the
  27. // table of contents if it was requested.
  28. //
  29. // The method will be passed an entire document tree, in case a particular
  30. // implementation needs to inspect it to produce output.
  31. //
  32. // The output should be written to the supplied writer w. If your
  33. // implementation has no header to write, supply an empty implementation.
  34. RenderHeader(w io.Writer, ast ast.Node)
  35. // RenderFooter is a symmetric counterpart of RenderHeader.
  36. RenderFooter(w io.Writer, ast ast.Node)
  37. }
  38. // Parse parsers a markdown document using provided parser. If parser is nil,
  39. // we use parser configured with parser.CommonExtensions.
  40. //
  41. // It returns AST (abstract syntax tree) that can be converted to another
  42. // format using Render function.
  43. func Parse(markdown []byte, p *parser.Parser) ast.Node {
  44. if p == nil {
  45. p = parser.New()
  46. }
  47. return p.Parse(markdown)
  48. }
  49. // Render uses renderer to convert parsed markdown document into a different format.
  50. //
  51. // To convert to HTML, pass html.Renderer
  52. func Render(doc ast.Node, renderer Renderer) []byte {
  53. var buf bytes.Buffer
  54. renderer.RenderHeader(&buf, doc)
  55. ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus {
  56. return renderer.RenderNode(&buf, node, entering)
  57. })
  58. renderer.RenderFooter(&buf, doc)
  59. return buf.Bytes()
  60. }
  61. // ToHTML converts markdownDoc to HTML.
  62. //
  63. // You can optionally pass a parser and renderer. This allows to customize
  64. // a parser, use a customized html render or use completely custom renderer.
  65. //
  66. // If you pass nil for both, we use parser configured with parser.CommonExtensions
  67. // and html.Renderer configured with html.CommonFlags.
  68. func ToHTML(markdown []byte, p *parser.Parser, renderer Renderer) []byte {
  69. doc := Parse(markdown, p)
  70. if renderer == nil {
  71. opts := html.RendererOptions{
  72. Flags: html.CommonFlags,
  73. }
  74. renderer = html.NewRenderer(opts)
  75. }
  76. return Render(doc, renderer)
  77. }
  78. // NormalizeNewlines converts Windows and Mac newlines to Unix newlines.
  79. // The parser only supports Unix newlines. If your markdown content
  80. // might contain Windows or Mac newlines, use this function to convert to Unix newlines
  81. var NormalizeNewlines = parser.NormalizeNewlines