1
0
mirror of https://github.com/danog/blackfriday.git synced 2024-11-30 04:29:13 +01:00

Add direct link to a footnote from it's referer

Some renderers might not care to have an explicit list of footnotes at
the end of the document, instead they're interested in the content of
the footnote at the location of a referer. Make their lives easier by
providing such a link
This commit is contained in:
Vytautas Šaltenis 2016-09-17 19:31:29 +03:00
parent b91b5719eb
commit 8a11177489
3 changed files with 17 additions and 7 deletions

View File

@ -297,6 +297,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
txtE := i
i++
var footnoteNode *Node
// skip any amount of whitespace or newline
// (this is much more lax than original markdown syntax)
@ -476,6 +477,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
}
}
footnoteNode = NewNode(Item)
if t == linkInlineFootnote {
// create a new reference
noteID = len(p.notes) + 1
@ -497,6 +499,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
hasBlock: false,
link: fragment,
title: id,
footnote: footnoteNode,
}
p.notes = append(p.notes, ref)
@ -512,6 +515,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
if t == linkDeferredFootnote {
lr.noteID = len(p.notes) + 1
lr.footnote = footnoteNode
p.notes = append(p.notes, lr)
}
@ -570,6 +574,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
linkNode.Destination = link
linkNode.Title = title
linkNode.NoteID = noteID
linkNode.Footnote = footnoteNode
if t == linkInlineFootnote {
i++
}

View File

@ -213,14 +213,16 @@ func (p *parser) finalize(block *Node) {
}
func (p *parser) addChild(node NodeType, offset uint32) *Node {
for !p.tip.canContain(node) {
return p.addExistingChild(NewNode(node), offset)
}
func (p *parser) addExistingChild(node *Node, offset uint32) *Node {
for !p.tip.canContain(node.Type) {
p.finalize(p.tip)
}
newNode := NewNode(node)
newNode.content = []byte{}
p.tip.AppendChild(newNode)
p.tip = newNode
return newNode
p.tip.AppendChild(node)
p.tip = node
return node
}
func (p *parser) closeUnmatchedBlocks() {
@ -419,7 +421,8 @@ func (p *parser) parseRefsToAST() {
// the fixed initial set.
for i := 0; i < len(p.notes); i++ {
ref := p.notes[i]
block := p.addBlock(Item, nil)
p.addExistingChild(ref.footnote, 0)
block := ref.footnote
block.ListFlags = flags | ListTypeOrdered
block.RefLink = ref.link
if ref.hasBlock {
@ -570,6 +573,7 @@ type reference struct {
title []byte
noteID int // 0 if not a footnote ref
hasBlock bool
footnote *Node // a link to the Item node within a list of footnotes
text []byte // only gets populated by refOverride feature with Reference.Text
}

View File

@ -84,6 +84,7 @@ type LinkData struct {
Destination []byte // Destination is what goes into a href
Title []byte // Title is the tooltip thing that goes in a title attribute
NoteID int // NoteID contains a serial number of a footnote, zero if it's not a footnote
Footnote *Node // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.
}
// CodeBlockData contains fields relevant to a CodeBlock node type.