diff --git a/extension/_test/footnote.txt b/extension/_test/footnote.txt
index 9b06721..6c82688 100644
--- a/extension/_test/footnote.txt
+++ b/extension/_test/footnote.txt
@@ -66,3 +66,21 @@ test![^1]
//= = = = = = = = = = = = = = = = = = = = = = = =//
+
+
+6
+//- - - - - - - - -//
+That's some text with a footnote.[^mynameisjeff]
+
+[^mynameisjeff]: And that's the footnote.
+//- - - - - - - - -//
+
That's some text with a footnote.
+
+//= = = = = = = = = = = = = = = = = = = = = = = =//
diff --git a/extension/footnote.go b/extension/footnote.go
index 972418e..bc0ec74 100644
--- a/extension/footnote.go
+++ b/extension/footnote.go
@@ -242,16 +242,36 @@ func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegist
reg.Register(ast.KindFootnoteList, r.renderFootnoteList)
}
+func isNumeric(b []byte) bool {
+ for _, c := range b {
+ if c < '0' || c > '9' {
+ return false
+ }
+ }
+ return true
+}
+
+// footnoteRef decides what to use to refer to the footnote. The
+// returned string is safe to use in HTML attributes.
+func footnoteRef(index int, ref []byte) []byte {
+ if !isNumeric(ref) {
+ return util.EscapeHTML(ref)
+ }
+ return strconv.AppendInt(nil, int64(index), 10)
+}
+
func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
if entering {
n := node.(*ast.FootnoteLink)
- is := strconv.Itoa(n.Index)
+ ref := footnoteRef(n.Index, n.Ref)
_, _ = w.WriteString(``)
}
return gast.WalkContinue, nil
@@ -260,9 +280,9 @@ 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) {
if entering {
n := node.(*ast.FootnoteBackLink)
- is := strconv.Itoa(n.Index)
+ ref := footnoteRef(n.Index, n.Ref)
_, _ = w.WriteString(` `)
@@ -272,10 +292,10 @@ func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source [
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)
if entering {
+ ref := footnoteRef(n.Index, n.Ref)
_, _ = w.WriteString(`