// Copyright 2015 The Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package markdown provides CommonMark-compliant markdown parser and renderer.
package markdown
import (
"bytes"
"io"
)
type Markdown struct {
options
Block ParserBlock
Inline ParserInline
renderOptions RenderOptions
}
type RenderOptions struct {
LangPrefix string // CSS language class prefix for fenced blocks
XHTML bool // render as XHTML instead of HTML
Breaks bool // convert \n in paragraphs into <br>
Nofollow bool // add rel="nofollow" to the links
}
type options struct {
HTML bool // allow raw HTML in the markup
Tables bool // GFM tables
Linkify bool // autoconvert URL-like text to links
Typographer bool // enable some typographic replacements
Quotes [4]string // double/single quotes replacement pairs
MaxNesting int // maximum nesting level
}
type Environment struct {
References map[string]map[string]string
}
type CoreRule func(*StateCore)
var coreRules []CoreRule
func New(opts ...option) *Markdown {
m := &Markdown{
options: options{
Tables: true,
Linkify: true,
Typographer: true,
Quotes: [4]string{"“", "”", "‘", "’"},
MaxNesting: 20,
},
renderOptions: RenderOptions{LangPrefix: "language-"},
}
for _, opt := range opts {
opt(m)
}
return m
}
func (m *Markdown) Parse(src []byte) []Token {
if len(src) == 0 {
return nil
}
s := &StateCore{
Md: m,
Env: &Environment{},
}
s.Tokens = m.Block.Parse(src, m, s.Env)
for _, r := range coreRules {
r(s)
}
return s.Tokens
}
func (m *Markdown) Render(w io.Writer, src []byte) error {
if len(src) == 0 {
return nil
}
return NewRenderer(w).Render(m.Parse(src), m.renderOptions)
}
func (m *Markdown) RenderTokens(w io.Writer, tokens []Token) error {
if len(tokens) == 0 {
return nil
}
return NewRenderer(w).Render(tokens, m.renderOptions)
}
func (m *Markdown) RenderToString(src []byte) string {
if len(src) == 0 {
return ""
}
var buf bytes.Buffer
NewRenderer(&buf).Render(m.Parse(src), m.renderOptions)
return buf.String()
}
func (m *Markdown) RenderTokensToString(tokens []Token) string {
if len(tokens) == 0 {
return ""
}
var buf bytes.Buffer
NewRenderer(&buf).Render(tokens, m.renderOptions)
return buf.String()
}