Move footnote rendering to the renderer

Clean up footnotes part of an AST: don't force HTML-specific pieces
there, just keep a clean list of footnotes. Since some renderers might
want to process footnotes differently, let them know about footnotes by
having a flag on that list.
This commit is contained in:
Vytautas Šaltenis 2016-09-03 12:39:16 +03:00
parent ea8dfc4880
commit 6947216efb
4 changed files with 25 additions and 16 deletions

12
html.go
View File

@ -589,10 +589,11 @@ func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkSt
tagName = "dl" tagName = "dl"
} }
if entering { if entering {
// var start = node.listStart; if node.IsFootnotesList {
// if (start !== null && start !== 1) { r.out(w, []byte("\n<div class=\"footnotes\">\n\n"))
// attrs.push(['start', start.toString()]); r.out(w, tag("hr", attrs, r.Flags&UseXHTML != 0))
// } r.cr(w)
}
r.cr(w) r.cr(w)
if node.Parent.Type == Item && node.Parent.Parent.Tight { if node.Parent.Type == Item && node.Parent.Parent.Tight {
r.cr(w) r.cr(w)
@ -611,6 +612,9 @@ func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkSt
if node.Parent.Type == Document || node.Parent.Type == BlockQuote { if node.Parent.Type == Document || node.Parent.Type == BlockQuote {
r.cr(w) r.cr(w)
} }
if node.IsFootnotesList {
r.out(w, []byte("\n</div>\n"))
}
} }
case Item: case Item:
tagName := "li" tagName := "li"

View File

@ -922,6 +922,12 @@ what happens here
</div> </div>
`, `,
`This text does not reference a footnote.
[^footnote]: But it has a footnote! And it gets omitted.
`,
"<p>This text does not reference a footnote.</p>\n",
} }
func TestFootnotes(t *testing.T) { func TestFootnotes(t *testing.T) {

View File

@ -416,9 +416,8 @@ func (p *parser) parseRefsToAST() {
return return
} }
p.tip = p.doc p.tip = p.doc
finalizeHTMLBlock(p.addBlock(HTMLBlock, []byte(`<div class="footnotes">`)))
p.addBlock(HorizontalRule, nil)
block := p.addBlock(List, nil) block := p.addBlock(List, nil)
block.IsFootnotesList = true
block.ListFlags = ListTypeOrdered block.ListFlags = ListTypeOrdered
flags := ListItemBeginningOfList flags := ListItemBeginningOfList
// Note: this loop is intentionally explicit, not range-form. This is // Note: this loop is intentionally explicit, not range-form. This is
@ -441,7 +440,6 @@ func (p *parser) parseRefsToAST() {
above := block.Parent above := block.Parent
finalizeList(block) finalizeList(block)
p.tip = above p.tip = above
finalizeHTMLBlock(p.addBlock(HTMLBlock, []byte("</div>")))
block.Walk(func(node *Node, entering bool) WalkStatus { block.Walk(func(node *Node, entering bool) WalkStatus {
if node.Type == Paragraph || node.Type == Header { if node.Type == Paragraph || node.Type == Header {
p.inline(node, node.content) p.inline(node, node.content)

19
node.go
View File

@ -69,20 +69,21 @@ func (t NodeType) String() string {
return nodeTypeNames[t] return nodeTypeNames[t]
} }
// ListData contains fields relevant to a List node type. // ListData contains fields relevant to a List and Item node type.
type ListData struct { type ListData struct {
ListFlags ListType ListFlags ListType
Tight bool // Skip <p>s around list item data if true Tight bool // Skip <p>s around list item data if true
BulletChar byte // '*', '+' or '-' in bullet lists BulletChar byte // '*', '+' or '-' in bullet lists
Delimiter byte // '.' or ')' after the number in ordered lists Delimiter byte // '.' or ')' after the number in ordered lists
RefLink []byte // If not nil, turns this list item into a footnote item and triggers different rendering RefLink []byte // If not nil, turns this list item into a footnote item and triggers different rendering
IsFootnotesList bool // This is a list of footnotes
} }
// LinkData contains fields relevant to a Link node type. // LinkData contains fields relevant to a Link node type.
type LinkData struct { type LinkData struct {
Destination []byte Destination []byte // Destination is what goes into a href
Title []byte Title []byte // Title is the tooltip thing that goes in a title attribute
NoteID int NoteID int // NoteID contains a serial number of a footnote, zero if it's not a footnote
} }
// CodeBlockData contains fields relevant to a CodeBlock node type. // CodeBlockData contains fields relevant to a CodeBlock node type.