Adding ability to use labeled footnotes.

This commit is contained in:
Shane Liesegang 2020-01-13 10:57:17 -05:00
parent faaafa55b6
commit 04acf85d56
2 changed files with 20 additions and 9 deletions

View file

@ -2,6 +2,7 @@ package ast
import ( import (
"fmt" "fmt"
gast "github.com/yuin/goldmark/ast" gast "github.com/yuin/goldmark/ast"
) )
@ -9,6 +10,7 @@ import (
// (PHP Markdown Extra) text. // (PHP Markdown Extra) text.
type FootnoteLink struct { type FootnoteLink struct {
gast.BaseInline gast.BaseInline
Ref []byte
Index int Index int
} }
@ -28,9 +30,10 @@ func (n *FootnoteLink) Kind() gast.NodeKind {
} }
// NewFootnoteLink returns a new FootnoteLink node. // NewFootnoteLink returns a new FootnoteLink node.
func NewFootnoteLink(index int) *FootnoteLink { func NewFootnoteLink(index int, ref []byte) *FootnoteLink {
return &FootnoteLink{ return &FootnoteLink{
Index: index, Index: index,
Ref: ref,
} }
} }
@ -38,6 +41,7 @@ func NewFootnoteLink(index int) *FootnoteLink {
// (PHP Markdown Extra) text. // (PHP Markdown Extra) text.
type FootnoteBackLink struct { type FootnoteBackLink struct {
gast.BaseInline gast.BaseInline
Ref []byte
Index int Index int
} }
@ -57,9 +61,10 @@ func (n *FootnoteBackLink) Kind() gast.NodeKind {
} }
// NewFootnoteBackLink returns a new FootnoteBackLink node. // NewFootnoteBackLink returns a new FootnoteBackLink node.
func NewFootnoteBackLink(index int) *FootnoteBackLink { func NewFootnoteBackLink(index int, ref []byte) *FootnoteBackLink {
return &FootnoteBackLink{ return &FootnoteBackLink{
Index: index, Index: index,
Ref: ref,
} }
} }

View file

@ -2,6 +2,8 @@ package extension
import ( import (
"bytes" "bytes"
"strconv"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
gast "github.com/yuin/goldmark/ast" gast "github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/extension/ast" "github.com/yuin/goldmark/extension/ast"
@ -10,7 +12,6 @@ import (
"github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/text" "github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
"strconv"
) )
var footnoteListKey = parser.NewContextKey() var footnoteListKey = parser.NewContextKey()
@ -149,8 +150,10 @@ func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Co
return nil return nil
} }
index := 0 index := 0
var ref []byte
for def := list.FirstChild(); def != nil; def = def.NextSibling() { for def := list.FirstChild(); def != nil; def = def.NextSibling() {
d := def.(*ast.Footnote) d := def.(*ast.Footnote)
ref = d.Ref
if bytes.Equal(d.Ref, value) { if bytes.Equal(d.Ref, value) {
if d.Index < 0 { if d.Index < 0 {
list.Count += 1 list.Count += 1
@ -164,7 +167,7 @@ func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Co
return nil return nil
} }
return ast.NewFootnoteLink(index) return ast.NewFootnoteLink(index, ref)
} }
type footnoteASTTransformer struct { type footnoteASTTransformer struct {
@ -193,10 +196,11 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read
container = fc container = fc
} }
index := footnote.(*ast.Footnote).Index index := footnote.(*ast.Footnote).Index
ref := footnote.(*ast.Footnote).Ref
if index < 0 { if index < 0 {
list.RemoveChild(list, footnote) list.RemoveChild(list, footnote)
} else { } else {
container.AppendChild(container, ast.NewFootnoteBackLink(index)) container.AppendChild(container, ast.NewFootnoteBackLink(index, ref))
} }
footnote = next footnote = next
} }
@ -243,10 +247,11 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt
if entering { if entering {
n := node.(*ast.FootnoteLink) n := node.(*ast.FootnoteLink)
is := strconv.Itoa(n.Index) is := strconv.Itoa(n.Index)
ref := string(n.Ref)
_, _ = w.WriteString(`<sup id="fnref:`) _, _ = w.WriteString(`<sup id="fnref:`)
_, _ = w.WriteString(is) _, _ = w.WriteString(ref)
_, _ = w.WriteString(`"><a href="#fn:`) _, _ = w.WriteString(`"><a href="#fn:`)
_, _ = w.WriteString(is) _, _ = w.WriteString(ref)
_, _ = w.WriteString(`" class="footnote-ref" role="doc-noteref">`) _, _ = w.WriteString(`" class="footnote-ref" role="doc-noteref">`)
_, _ = w.WriteString(is) _, _ = w.WriteString(is)
_, _ = w.WriteString(`</a></sup>`) _, _ = w.WriteString(`</a></sup>`)
@ -257,9 +262,10 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt
func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
if entering { if entering {
n := node.(*ast.FootnoteBackLink) n := node.(*ast.FootnoteBackLink)
is := strconv.Itoa(n.Index) // is := strconv.Itoa(n.Index)
ref := string(n.Ref)
_, _ = w.WriteString(` <a href="#fnref:`) _, _ = w.WriteString(` <a href="#fnref:`)
_, _ = w.WriteString(is) _, _ = w.WriteString(ref)
_, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`) _, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`)
_, _ = w.WriteString("&#x21a9;&#xfe0e;") _, _ = w.WriteString("&#x21a9;&#xfe0e;")
_, _ = w.WriteString(`</a>`) _, _ = w.WriteString(`</a>`)