Enable full AST construction, use the new renderer Connect the block and inline parsers. Most of the tests now pass, only a couple fail, they need fixes in the test suite.
Vytautas Ĺ altenis vytas@rtfb.lt
Wed, 30 Mar 2016 14:47:30 +0300
2 files changed,
71 insertions(+),
2 deletions(-)
M
markdown.go
→
markdown.go
@@ -206,6 +206,8 @@ CaptureWrites(processor func()) []byte
CopyWrites(processor func()) []byte Write(b []byte) (int, error) GetResult() []byte + + Render(ast *Node) []byte } // Callback functions for inline parsing. One such function is defined@@ -437,8 +439,71 @@ p.notes = make([]*reference, 0)
} first := firstPass(p, input) - second := secondPass(p, first) - return second + secondPass(p, first) + // walk the tree and finish up some of unfinished blocks: + for p.tip != nil { + p.finalize(p.tip) + } + ForEachNode(p.doc, func(node *Node, entering bool) { + if node.Type == Paragraph || node.Type == Header || node.Type == TableCell { + p.currBlock = node + p.inline(node.content) + node.content = nil + } + }) + p.parseRefsToAST() + return renderer.Render(p.doc) +} + +func (p *parser) parseRefsToAST() { + if p.flags&Footnotes == 0 || len(p.notes) == 0 { + return + } + p.tip = p.doc + finalizeHtmlBlock(p.addBlock(HtmlBlock, []byte(`<div class="footnotes">`))) + p.addBlock(HorizontalRule, nil) + block := p.addBlock(List, nil) + block.ListData = &ListData{ // TODO: fill in the real ListData + Flags: ListTypeOrdered, + Tight: false, + BulletChar: '*', + Delimiter: 0, + } + flags := ListItemBeginningOfList + // Note: this loop is intentionally explicit, not range-form. This is + // because the body of the loop will append nested footnotes to p.notes and + // we need to process those late additions. Range form would only walk over + // the fixed initial set. + for i := 0; i < len(p.notes); i++ { + ref := p.notes[i] + block := p.addBlock(Item, nil) + block.ListData = &ListData{ // TODO: fill in the real ListData + Flags: ListTypeOrdered, + Tight: false, + BulletChar: '*', + Delimiter: 0, + RefLink: ref.link, + } + if ref.hasBlock { + flags |= ListItemContainsBlock + p.block(ref.title) + } else { + p.currBlock = block + p.inline(ref.title) + } + flags &^= ListItemBeginningOfList | ListItemContainsBlock + } + above := block.Parent + finalizeList(block) + p.tip = above + finalizeHtmlBlock(p.addBlock(HtmlBlock, []byte("</div>"))) + ForEachNode(block, func(node *Node, entering bool) { + if node.Type == Paragraph || node.Type == Header { + p.currBlock = node + p.inline(node.content) + node.content = nil + } + }) } // first pass: