markdown/markdown.go

79 lines
2.7 KiB
Go
Raw Normal View History

2018-01-25 13:01:19 -08:00
package markdown
2011-05-24 16:14:35 -06:00
import (
2018-01-27 18:50:27 -08:00
"bytes"
2016-07-05 07:32:16 +03:00
"io"
2018-01-27 18:00:30 -08:00
"github.com/gomarkdown/markdown/ast"
2018-01-27 18:39:03 -08:00
"github.com/gomarkdown/markdown/html"
2018-01-27 18:50:27 -08:00
"github.com/gomarkdown/markdown/parser"
2011-05-24 16:14:35 -06:00
)
// Renderer is an interface for implementing custom renderers.
2011-06-29 11:13:17 -06:00
type Renderer interface {
// RenderNode is the main rendering method. It will be called once for
// every leaf node and twice for every non-leaf node (first with
2017-07-30 19:50:50 +03:00
// entering=true, then with entering=false). The method should write its
// rendition of the node to writer w.
2018-01-28 00:50:21 -08:00
RenderNode(w io.Writer, node ast.Node, entering bool) ast.WalkStatus
// RenderHeader is a method that allows the renderer to produce some
// content preceding the main body of the output document. The header is
// understood in the broad sense here. For example, the default HTML
// renderer will write not only the HTML document preamble, but also the
// table of contents if it was requested.
//
// The method will be passed an entire document tree, in case a particular
// implementation needs to inspect it to produce output.
//
// The output should be written to the supplied writer w. If your
// implementation has no header to write, supply an empty implementation.
2018-01-28 00:50:21 -08:00
RenderHeader(w io.Writer, ast ast.Node)
// RenderFooter is a symmetric counterpart of RenderHeader.
2018-01-28 00:50:21 -08:00
RenderFooter(w io.Writer, ast ast.Node)
2011-05-24 16:14:35 -06:00
}
2018-01-28 18:38:27 -08:00
// Parse parsers a markdown document using provided parser. If parser is nil,
// we use parser configured with parser.CommonExtensions.
2018-01-28 13:13:03 -08:00
//
2018-01-28 18:38:27 -08:00
// It returns AST (abstract syntax tree) that can be converted to another
// format using Render function.
2018-01-28 13:13:03 -08:00
func Parse(markdown []byte, p *parser.Parser) ast.Node {
if p == nil {
p = parser.New()
}
return p.Parse(markdown)
}
2018-01-27 20:44:39 -08:00
// Render uses renderer to convert parsed markdown document into a different format.
2018-01-28 13:13:03 -08:00
//
2018-01-28 18:38:27 -08:00
// To convert to HTML, pass html.Renderer
2018-01-28 00:50:21 -08:00
func Render(doc ast.Node, renderer Renderer) []byte {
2018-01-27 18:50:27 -08:00
var buf bytes.Buffer
2018-01-27 20:44:39 -08:00
renderer.RenderHeader(&buf, doc)
2018-01-28 00:50:21 -08:00
ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus {
2018-01-27 18:50:27 -08:00
return renderer.RenderNode(&buf, node, entering)
})
2018-01-27 20:44:39 -08:00
renderer.RenderFooter(&buf, doc)
2018-01-27 18:50:27 -08:00
return buf.Bytes()
}
2018-01-27 20:44:39 -08:00
// ToHTML converts markdownDoc to HTML.
//
2018-01-27 20:44:39 -08:00
// You can optionally pass a parser and renderer. This allows to customize
// a parser, use a customized html render or use completely custom renderer.
//
2018-01-27 20:44:39 -08:00
// If you pass nil for both, we use parser configured with parser.CommonExtensions
// and html.Renderer configured with html.CommonFlags.
2018-01-28 13:13:03 -08:00
func ToHTML(markdown []byte, p *parser.Parser, renderer Renderer) []byte {
2018-01-28 13:21:53 -08:00
doc := Parse(markdown, p)
2018-01-26 00:11:58 -08:00
if renderer == nil {
2018-01-27 18:50:27 -08:00
opts := html.RendererOptions{
2018-01-27 18:39:03 -08:00
Flags: html.CommonFlags,
2018-01-26 00:11:58 -08:00
}
2018-01-27 18:50:27 -08:00
renderer = html.NewRenderer(opts)
}
2018-01-27 20:44:39 -08:00
return Render(doc, renderer)
2018-01-25 23:15:51 -08:00
}