2018-01-25 21:01:19 +00:00
|
|
|
package markdown
|
2011-05-24 22:14:35 +00:00
|
|
|
|
|
|
|
import (
|
2018-01-28 02:50:27 +00:00
|
|
|
"bytes"
|
2016-07-05 04:32:16 +00:00
|
|
|
"io"
|
2018-01-28 02:00:30 +00:00
|
|
|
|
|
|
|
"github.com/gomarkdown/markdown/ast"
|
2018-01-28 02:39:03 +00:00
|
|
|
"github.com/gomarkdown/markdown/html"
|
2018-01-28 02:50:27 +00:00
|
|
|
"github.com/gomarkdown/markdown/parser"
|
2011-05-24 22:14:35 +00:00
|
|
|
)
|
|
|
|
|
2018-01-26 22:21:26 +00:00
|
|
|
// Renderer is an interface for implementing custom renderers.
|
2011-06-29 17:13:17 +00:00
|
|
|
type Renderer interface {
|
2017-07-09 12:20:34 +00:00
|
|
|
// 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 16:50:50 +00:00
|
|
|
// entering=true, then with entering=false). The method should write its
|
2018-01-26 22:21:26 +00:00
|
|
|
// rendition of the node to writer w.
|
2018-01-28 08:50:21 +00:00
|
|
|
RenderNode(w io.Writer, node ast.Node, entering bool) ast.WalkStatus
|
2017-07-09 12:20:34 +00:00
|
|
|
|
|
|
|
// 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 08:50:21 +00:00
|
|
|
RenderHeader(w io.Writer, ast ast.Node)
|
2017-07-09 12:20:34 +00:00
|
|
|
|
|
|
|
// RenderFooter is a symmetric counterpart of RenderHeader.
|
2018-01-28 08:50:21 +00:00
|
|
|
RenderFooter(w io.Writer, ast ast.Node)
|
2011-05-24 22:14:35 +00:00
|
|
|
}
|
|
|
|
|
2018-01-29 02:38:27 +00:00
|
|
|
// Parse parsers a markdown document using provided parser. If parser is nil,
|
|
|
|
// we use parser configured with parser.CommonExtensions.
|
2018-01-28 21:13:03 +00:00
|
|
|
//
|
2018-01-29 02:38:27 +00:00
|
|
|
// It returns AST (abstract syntax tree) that can be converted to another
|
|
|
|
// format using Render function.
|
2018-01-28 21:13:03 +00:00
|
|
|
func Parse(markdown []byte, p *parser.Parser) ast.Node {
|
|
|
|
if p == nil {
|
|
|
|
p = parser.New()
|
|
|
|
}
|
|
|
|
return p.Parse(markdown)
|
|
|
|
}
|
|
|
|
|
2018-01-28 04:44:39 +00:00
|
|
|
// Render uses renderer to convert parsed markdown document into a different format.
|
2018-01-28 21:13:03 +00:00
|
|
|
//
|
2018-01-29 02:38:27 +00:00
|
|
|
// To convert to HTML, pass html.Renderer
|
2018-01-28 08:50:21 +00:00
|
|
|
func Render(doc ast.Node, renderer Renderer) []byte {
|
2018-01-28 02:50:27 +00:00
|
|
|
var buf bytes.Buffer
|
2018-01-28 04:44:39 +00:00
|
|
|
renderer.RenderHeader(&buf, doc)
|
2018-01-28 08:50:21 +00:00
|
|
|
ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus {
|
2018-01-28 02:50:27 +00:00
|
|
|
return renderer.RenderNode(&buf, node, entering)
|
|
|
|
})
|
2018-01-28 04:44:39 +00:00
|
|
|
renderer.RenderFooter(&buf, doc)
|
2018-01-28 02:50:27 +00:00
|
|
|
return buf.Bytes()
|
|
|
|
}
|
|
|
|
|
2018-01-28 04:44:39 +00:00
|
|
|
// ToHTML converts markdownDoc to HTML.
|
2017-02-02 07:35:10 +00:00
|
|
|
//
|
2018-01-28 04:44:39 +00: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.
|
2017-02-02 07:35:10 +00:00
|
|
|
//
|
2018-01-28 04:44:39 +00:00
|
|
|
// If you pass nil for both, we use parser configured with parser.CommonExtensions
|
|
|
|
// and html.Renderer configured with html.CommonFlags.
|
2018-01-28 21:13:03 +00:00
|
|
|
func ToHTML(markdown []byte, p *parser.Parser, renderer Renderer) []byte {
|
2018-01-28 21:21:53 +00:00
|
|
|
doc := Parse(markdown, p)
|
2018-01-26 08:11:58 +00:00
|
|
|
if renderer == nil {
|
2018-01-28 02:50:27 +00:00
|
|
|
opts := html.RendererOptions{
|
2018-01-28 02:39:03 +00:00
|
|
|
Flags: html.CommonFlags,
|
2018-01-26 08:11:58 +00:00
|
|
|
}
|
2018-01-28 02:50:27 +00:00
|
|
|
renderer = html.NewRenderer(opts)
|
2017-02-02 07:35:10 +00:00
|
|
|
}
|
2018-01-28 04:44:39 +00:00
|
|
|
return Render(doc, renderer)
|
2018-01-26 07:15:51 +00:00
|
|
|
}
|