diff --git a/extension/_test/footnote.txt b/extension/_test/footnote.txt index 49f07aa..ef1553a 100644 --- a/extension/_test/footnote.txt +++ b/extension/_test/footnote.txt @@ -12,7 +12,7 @@ That's some text with a footnote.[^1]
  1. And that's the footnote.

    -

    That's the second paragraph.

    +

    That's the second paragraph.

diff --git a/extension/ast/footnote.go b/extension/ast/footnote.go index ab60b70..291e6b3 100644 --- a/extension/ast/footnote.go +++ b/extension/ast/footnote.go @@ -34,6 +34,35 @@ func NewFootnoteLink(index int) *FootnoteLink { } } +// A FootnoteBackLink struct represents a link to a footnote of Markdown +// (PHP Markdown Extra) text. +type FootnoteBackLink struct { + gast.BaseInline + Index int +} + +// Dump implements Node.Dump. +func (n *FootnoteBackLink) Dump(source []byte, level int) { + m := map[string]string{} + m["Index"] = fmt.Sprintf("%v", n.Index) + gast.DumpHelper(n, source, level, m, nil) +} + +// KindFootnoteBackLink is a NodeKind of the FootnoteBackLink node. +var KindFootnoteBackLink = gast.NewNodeKind("FootnoteBackLink") + +// Kind implements Node.Kind. +func (n *FootnoteBackLink) Kind() gast.NodeKind { + return KindFootnoteBackLink +} + +// NewFootnoteBackLink returns a new FootnoteBackLink node. +func NewFootnoteBackLink(index int) *FootnoteBackLink { + return &FootnoteBackLink{ + Index: index, + } +} + // A Footnote struct represents a footnote of Markdown // (PHP Markdown Extra) text. type Footnote struct { diff --git a/extension/footnote.go b/extension/footnote.go index 9be7f41..ccafdeb 100644 --- a/extension/footnote.go +++ b/extension/footnote.go @@ -180,6 +180,16 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read return } pc.Set(footnoteListKey, nil) + + for footnote := list.FirstChild(); footnote != nil; footnote = footnote.NextSibling() { + var container gast.Node = footnote + if fc := container.LastChild(); fc != nil && gast.IsParagraph(fc) { + container = fc + } + index := footnote.(*ast.Footnote).Index + container.AppendChild(container, ast.NewFootnoteBackLink(index)) + } + node.AppendChild(node, list) } @@ -203,6 +213,7 @@ func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { // RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(ast.KindFootnoteLink, r.renderFootnoteLink) + reg.Register(ast.KindFootnoteBackLink, r.renderFootnoteBackLink) reg.Register(ast.KindFootnote, r.renderFootnote) reg.Register(ast.KindFootnoteList, r.renderFootnoteList) } @@ -222,6 +233,19 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt return gast.WalkContinue, nil } +func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + n := node.(*ast.FootnoteBackLink) + is := strconv.Itoa(n.Index) + _, _ = w.WriteString(``) + _, _ = w.WriteString("↩") + _, _ = w.WriteString(``) + } + return gast.WalkContinue, nil +} + func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { n := node.(*ast.Footnote) is := strconv.Itoa(n.Index)