func New(opts ...Option) *Markdown {
	var p Markdown
	for _, opt := range opts {
		opt(&p)
	}
	p.refs = make(map[string]*reference)
	p.maxNesting = 16
	p.insideLink = false
	docNode := NewNode(Document)
	p.doc = docNode
	p.tip = docNode
	p.oldTip = docNode
	p.lastMatchedContainer = docNode
	p.allClosed = true
	p.inlineCallback[' '] = maybeLineBreak
	p.inlineCallback['*'] = emphasis
	p.inlineCallback['_'] = emphasis
	if p.extensions&Strikethrough != 0 {
		p.inlineCallback['~'] = emphasis
	}
	p.inlineCallback['`'] = codeSpan
	p.inlineCallback['\n'] = lineBreak
	p.inlineCallback['['] = link
	p.inlineCallback['<'] = leftAngle
	p.inlineCallback['\\'] = escape
	p.inlineCallback['&'] = entity
	p.inlineCallback['!'] = maybeImage
	p.inlineCallback['^'] = maybeInlineFootnote
	if p.extensions&Autolink != 0 {
		p.inlineCallback['h'] = maybeAutoLink
		p.inlineCallback['m'] = maybeAutoLink
		p.inlineCallback['f'] = maybeAutoLink
		p.inlineCallback['H'] = maybeAutoLink
		p.inlineCallback['M'] = maybeAutoLink
		p.inlineCallback['F'] = maybeAutoLink
	}
	if p.extensions&Footnotes != 0 {
		p.notes = make([]*reference, 0)
	}
	return &p
}
New constructs a Markdown processor. You can use the same With* functions as
for Run() to customize parser's behavior and the renderer.
package blackfriday
import (
	"bytes"
	"fmt"
	"io"
	"strings"
	"unicode/utf8"
)
const Version = "2.0"
type Extensions int
const (
	NoExtensions           Extensions = 0
	NoIntraEmphasis        Extensions = 1 << iota  
	Tables                                         
	FencedCode                                     
	Autolink                                       
	Strikethrough                                  
	LaxHTMLBlocks                                  
	SpaceHeadings                                  
	HardLineBreak                                  
	TabSizeEight                                   
	Footnotes                                      
	NoEmptyLineBeforeBlock                         
	HeadingIDs                                     
	Titleblock                                     
	AutoHeadingIDs                                 
	BackslashLineBreak                             
	DefinitionLists                                
	CommonHTMLFlags HTMLFlags = UseXHTML | Smartypants |
		SmartypantsFractions | SmartypantsDashes | SmartypantsLatexDashes
	CommonExtensions Extensions = NoIntraEmphasis | Tables | FencedCode |
		Autolink | Strikethrough | SpaceHeadings | HeadingIDs |
		BackslashLineBreak | DefinitionLists
)
type ListType int
const (
	ListTypeOrdered ListType = 1 << iota
	ListTypeDefinition
	ListTypeTerm
	ListItemContainsBlock
	ListItemBeginningOfList  
	ListItemEndOfList
)
type CellAlignFlags int
const (
	TableAlignmentLeft CellAlignFlags = 1 << iota
	TableAlignmentRight
	TableAlignmentCenter = (TableAlignmentLeft | TableAlignmentRight)
)
const (
	TabSizeDefault = 4
	TabSizeDouble  = 8
)
var blockTags = map[string]struct{}{
	"blockquote": {},
	"del":        {},
	"div":        {},
	"dl":         {},
	"fieldset":   {},
	"form":       {},
	"h1":         {},
	"h2":         {},
	"h3":         {},
	"h4":         {},
	"h5":         {},
	"h6":         {},
	"iframe":     {},
	"ins":        {},
	"math":       {},
	"noscript":   {},
	"ol":         {},
	"pre":        {},
	"p":          {},
	"script":     {},
	"style":      {},
	"table":      {},
	"ul":         {},
	"address":    {},
	"article":    {},
	"aside":      {},
	"canvas":     {},
	"figcaption": {},
	"figure":     {},
	"footer":     {},
	"header":     {},
	"hgroup":     {},
	"main":       {},
	"nav":        {},
	"output":     {},
	"progress":   {},
	"section":    {},
	"video":      {},
}
type Renderer interface {
	RenderNode(w io.Writer, node *Node, entering bool) WalkStatus
	RenderHeader(w io.Writer, ast *Node)
	RenderFooter(w io.Writer, ast *Node)
}
type inlineParser func(p *Markdown, data []byte, offset int) (int, *Node)
type Markdown struct {
	renderer          Renderer
	referenceOverride ReferenceOverrideFunc
	refs              map[string]*reference
	inlineCallback    [256]inlineParser
	extensions        Extensions
	nesting           int
	maxNesting        int
	insideLink        bool
	notes []*reference
	doc                  *Node
	tip                  *Node  
	oldTip               *Node
	lastMatchedContainer *Node  
	allClosed            bool
}
func (p *Markdown) getRef(refid string) (ref *reference, found bool) {
	if p.referenceOverride != nil {
		r, overridden := p.referenceOverride(refid)
		if overridden {
			if r == nil {
				return nil, false
			}
			return &reference{
				link:     []byte(r.Link),
				title:    []byte(r.Title),
				noteID:   0,
				hasBlock: false,
				text:     []byte(r.Text)}, true
		}
	}
	ref, found = p.refs[strings.ToLower(refid)]
	return ref, found
}
func (p *Markdown) finalize(block *Node) {
	above := block.Parent
	block.open = false
	p.tip = above
}
func (p *Markdown) addChild(node NodeType, offset uint32) *Node {
	return p.addExistingChild(NewNode(node), offset)
}
func (p *Markdown) addExistingChild(node *Node, offset uint32) *Node {
	for !p.tip.canContain(node.Type) {
		p.finalize(p.tip)
	}
	p.tip.AppendChild(node)
	p.tip = node
	return node
}
func (p *Markdown) closeUnmatchedBlocks() {
	if !p.allClosed {
		for p.oldTip != p.lastMatchedContainer {
			parent := p.oldTip.Parent
			p.finalize(p.oldTip)
			p.oldTip = parent
		}
		p.allClosed = true
	}
}
type Reference struct {
	Link string
	Title string
	Text string
}
type ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool)