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:
parent
b91b5719eb
commit
8a11177489
|
@ -297,6 +297,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
|
||||||
|
|
||||||
txtE := i
|
txtE := i
|
||||||
i++
|
i++
|
||||||
|
var footnoteNode *Node
|
||||||
|
|
||||||
// skip any amount of whitespace or newline
|
// skip any amount of whitespace or newline
|
||||||
// (this is much more lax than original markdown syntax)
|
// (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 {
|
if t == linkInlineFootnote {
|
||||||
// create a new reference
|
// create a new reference
|
||||||
noteID = len(p.notes) + 1
|
noteID = len(p.notes) + 1
|
||||||
|
@ -497,6 +499,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
|
||||||
hasBlock: false,
|
hasBlock: false,
|
||||||
link: fragment,
|
link: fragment,
|
||||||
title: id,
|
title: id,
|
||||||
|
footnote: footnoteNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.notes = append(p.notes, ref)
|
p.notes = append(p.notes, ref)
|
||||||
|
@ -512,6 +515,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
|
||||||
|
|
||||||
if t == linkDeferredFootnote {
|
if t == linkDeferredFootnote {
|
||||||
lr.noteID = len(p.notes) + 1
|
lr.noteID = len(p.notes) + 1
|
||||||
|
lr.footnote = footnoteNode
|
||||||
p.notes = append(p.notes, lr)
|
p.notes = append(p.notes, lr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,6 +574,7 @@ func link(p *parser, data []byte, offset int) (int, *Node) {
|
||||||
linkNode.Destination = link
|
linkNode.Destination = link
|
||||||
linkNode.Title = title
|
linkNode.Title = title
|
||||||
linkNode.NoteID = noteID
|
linkNode.NoteID = noteID
|
||||||
|
linkNode.Footnote = footnoteNode
|
||||||
if t == linkInlineFootnote {
|
if t == linkInlineFootnote {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
18
markdown.go
18
markdown.go
|
@ -213,14 +213,16 @@ func (p *parser) finalize(block *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) addChild(node NodeType, offset uint32) *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)
|
p.finalize(p.tip)
|
||||||
}
|
}
|
||||||
newNode := NewNode(node)
|
p.tip.AppendChild(node)
|
||||||
newNode.content = []byte{}
|
p.tip = node
|
||||||
p.tip.AppendChild(newNode)
|
return node
|
||||||
p.tip = newNode
|
|
||||||
return newNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) closeUnmatchedBlocks() {
|
func (p *parser) closeUnmatchedBlocks() {
|
||||||
|
@ -419,7 +421,8 @@ func (p *parser) parseRefsToAST() {
|
||||||
// the fixed initial set.
|
// the fixed initial set.
|
||||||
for i := 0; i < len(p.notes); i++ {
|
for i := 0; i < len(p.notes); i++ {
|
||||||
ref := 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.ListFlags = flags | ListTypeOrdered
|
||||||
block.RefLink = ref.link
|
block.RefLink = ref.link
|
||||||
if ref.hasBlock {
|
if ref.hasBlock {
|
||||||
|
@ -570,6 +573,7 @@ type reference struct {
|
||||||
title []byte
|
title []byte
|
||||||
noteID int // 0 if not a footnote ref
|
noteID int // 0 if not a footnote ref
|
||||||
hasBlock bool
|
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
|
text []byte // only gets populated by refOverride feature with Reference.Text
|
||||||
}
|
}
|
||||||
|
|
1
node.go
1
node.go
|
@ -84,6 +84,7 @@ type LinkData struct {
|
||||||
Destination []byte // Destination is what goes into a href
|
Destination []byte // Destination is what goes into a href
|
||||||
Title []byte // Title is the tooltip thing that goes in a title attribute
|
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
|
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.
|
// CodeBlockData contains fields relevant to a CodeBlock node type.
|
||||||
|
|
Loading…
Reference in New Issue