This commit is contained in:
yuin 2022-04-14 15:10:12 +09:00
parent e29c1a5dfa
commit 6bdcc0f927
5 changed files with 65 additions and 13 deletions

View file

@ -19,7 +19,7 @@ run: $(CMARK_BIN)
GOOS=windows GOARCH=amd64 go build -o goldmark_benchmark.exe ./goldmark_benchmark.go && ./goldmark_benchmark.exe; \ GOOS=windows GOARCH=amd64 go build -o goldmark_benchmark.exe ./goldmark_benchmark.go && ./goldmark_benchmark.exe; \
fi fi
./cmark-master/build/src/config.h: ./cmark-master/Makefile:
wget -nc -O cmark.zip https://github.com/commonmark/cmark/archive/master.zip wget -nc -O cmark.zip https://github.com/commonmark/cmark/archive/master.zip
unzip cmark.zip unzip cmark.zip
rm -f cmark.zip rm -f cmark.zip
@ -29,7 +29,7 @@ run: $(CMARK_BIN)
cd cmark-master && make mingw; \ cd cmark-master && make mingw; \
fi fi
$(CMARK_BIN): ./cmark-master/build/src/config.h $(CMARK_BIN): ./cmark-master/Makefile
@ if [ -z "$${WSL_INTEROP}" ]; then \ @ if [ -z "$${WSL_INTEROP}" ]; then \
gcc -I./cmark-master/build/src -I./cmark-master/src cmark_benchmark.c -o $(CMARK_BIN) -L./cmark-master/build/src -lcmark; \ gcc -I./cmark-master/build/src -I./cmark-master/src cmark_benchmark.c -o $(CMARK_BIN) -L./cmark-master/build/src -lcmark; \
else \ else \

View file

@ -66,3 +66,26 @@ test![^1]
</ol> </ol>
</section> </section>
//= = = = = = = = = = = = = = = = = = = = = = = =// //= = = = = = = = = = = = = = = = = = = = = = = =//
6: Multiple references to the same footnotes should have different ids
//- - - - - - - - -//
something[^fn:1]
something[^fn:1]
something[^fn:1]
[^fn:1]: footnote text
//- - - - - - - - -//
<p>something<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>something<sup id="fnref1:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>something<sup id="fnref2:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<section class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1" role="doc-endnote">
<p>footnote text&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref2:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</section>
//= = = = = = = = = = = = = = = = = = = = = = = =//

View file

@ -12,6 +12,7 @@ type FootnoteLink struct {
gast.BaseInline gast.BaseInline
Index int Index int
RefCount int RefCount int
RefIndex int
} }
// Dump implements Node.Dump. // Dump implements Node.Dump.
@ -19,6 +20,7 @@ func (n *FootnoteLink) Dump(source []byte, level int) {
m := map[string]string{} m := map[string]string{}
m["Index"] = fmt.Sprintf("%v", n.Index) m["Index"] = fmt.Sprintf("%v", n.Index)
m["RefCount"] = fmt.Sprintf("%v", n.RefCount) m["RefCount"] = fmt.Sprintf("%v", n.RefCount)
m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex)
gast.DumpHelper(n, source, level, m, nil) gast.DumpHelper(n, source, level, m, nil)
} }
@ -35,6 +37,7 @@ func NewFootnoteLink(index int) *FootnoteLink {
return &FootnoteLink{ return &FootnoteLink{
Index: index, Index: index,
RefCount: 0, RefCount: 0,
RefIndex: 0,
} }
} }
@ -44,6 +47,7 @@ type FootnoteBacklink struct {
gast.BaseInline gast.BaseInline
Index int Index int
RefCount int RefCount int
RefIndex int
} }
// Dump implements Node.Dump. // Dump implements Node.Dump.
@ -51,6 +55,7 @@ func (n *FootnoteBacklink) Dump(source []byte, level int) {
m := map[string]string{} m := map[string]string{}
m["Index"] = fmt.Sprintf("%v", n.Index) m["Index"] = fmt.Sprintf("%v", n.Index)
m["RefCount"] = fmt.Sprintf("%v", n.RefCount) m["RefCount"] = fmt.Sprintf("%v", n.RefCount)
m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex)
gast.DumpHelper(n, source, level, m, nil) gast.DumpHelper(n, source, level, m, nil)
} }
@ -67,6 +72,7 @@ func NewFootnoteBacklink(index int) *FootnoteBacklink {
return &FootnoteBacklink{ return &FootnoteBacklink{
Index: index, Index: index,
RefCount: 0, RefCount: 0,
RefIndex: 0,
} }
} }

View file

@ -2,6 +2,7 @@ package extension
import ( import (
"bytes" "bytes"
"fmt"
"strconv" "strconv"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
@ -217,8 +218,14 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read
counter[fnlink.Index]++ counter[fnlink.Index]++
} }
} }
refCounter := map[int]int{}
for _, fnlink := range fnlist { for _, fnlink := range fnlist {
fnlink.RefCount = counter[fnlink.Index] fnlink.RefCount = counter[fnlink.Index]
if _, ok := refCounter[fnlink.Index]; !ok {
refCounter[fnlink.Index] = 0
}
fnlink.RefIndex = refCounter[fnlink.Index]
refCounter[fnlink.Index]++
} }
} }
for footnote := list.FirstChild(); footnote != nil; { for footnote := list.FirstChild(); footnote != nil; {
@ -232,9 +239,19 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read
if index < 0 { if index < 0 {
list.RemoveChild(list, footnote) list.RemoveChild(list, footnote)
} else { } else {
refCount := counter[index]
backLink := ast.NewFootnoteBacklink(index) backLink := ast.NewFootnoteBacklink(index)
backLink.RefCount = counter[index] backLink.RefCount = refCount
backLink.RefIndex = 0
container.AppendChild(container, backLink) container.AppendChild(container, backLink)
if refCount > 1 {
for i := 1; i < refCount; i++ {
backLink := ast.NewFootnoteBacklink(index)
backLink.RefCount = refCount
backLink.RefIndex = i
container.AppendChild(container, backLink)
}
}
} }
footnote = next footnote = next
} }
@ -514,7 +531,11 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt
is := strconv.Itoa(n.Index) is := strconv.Itoa(n.Index)
_, _ = w.WriteString(`<sup id="`) _, _ = w.WriteString(`<sup id="`)
_, _ = w.Write(r.idPrefix(node)) _, _ = w.Write(r.idPrefix(node))
_, _ = w.WriteString(`fnref:`) _, _ = w.WriteString(`fnref`)
if n.RefIndex > 0 {
_, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex))
}
_ = w.WriteByte(':')
_, _ = w.WriteString(is) _, _ = w.WriteString(is)
_, _ = w.WriteString(`"><a href="#`) _, _ = w.WriteString(`"><a href="#`)
_, _ = w.Write(r.idPrefix(node)) _, _ = w.Write(r.idPrefix(node))
@ -541,7 +562,11 @@ func (r *FootnoteHTMLRenderer) renderFootnoteBacklink(w util.BufWriter, source [
is := strconv.Itoa(n.Index) is := strconv.Itoa(n.Index)
_, _ = w.WriteString(`&#160;<a href="#`) _, _ = w.WriteString(`&#160;<a href="#`)
_, _ = w.Write(r.idPrefix(node)) _, _ = w.Write(r.idPrefix(node))
_, _ = w.WriteString(`fnref:`) _, _ = w.WriteString(`fnref`)
if n.RefIndex > 0 {
_, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex))
}
_ = w.WriteByte(':')
_, _ = w.WriteString(is) _, _ = w.WriteString(is)
_, _ = w.WriteString(`" class="`) _, _ = w.WriteString(`" class="`)
_, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkClass, n.Index, n.RefCount)) _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkClass, n.Index, n.RefCount))

View file

@ -63,20 +63,19 @@ Another one.[^2]
[^2]: Another footnote. [^2]: Another footnote.
`, `,
Expected: `<p>That's some text with a footnote.<sup id="article12-fnref:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p> Expected: `<p>That's some text with a footnote.<sup id="article12-fnref:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p>
<p>Same footnote.<sup id="article12-fnref:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p> <p>Same footnote.<sup id="article12-fnref1:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p>
<p>Another one.<sup id="article12-fnref:2"><a href="#article12-fn:2" class="link-class" title="link-title-1-2" role="doc-noteref">2</a></sup></p> <p>Another one.<sup id="article12-fnref:2"><a href="#article12-fn:2" class="link-class" title="link-title-1-2" role="doc-noteref">2</a></sup></p>
<section class="footnotes" role="doc-endnotes"> <section class="footnotes" role="doc-endnotes">
<hr> <hr>
<ol> <ol>
<li id="article12-fn:1" role="doc-endnote"> <li id="article12-fn:1" role="doc-endnote">
<p>And that's the footnote.&#160;<a href="#article12-fnref:1" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p> <p>And that's the footnote.&#160;<a href="#article12-fnref:1" class="backlink-class" title="backlink-title" role="doc-backlink">^</a>&#160;<a href="#article12-fnref1:1" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p>
</li> </li>
<li id="article12-fn:2" role="doc-endnote"> <li id="article12-fn:2" role="doc-endnote">
<p>Another footnote.&#160;<a href="#article12-fnref:2" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p> <p>Another footnote.&#160;<a href="#article12-fnref:2" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p>
</li> </li>
</ol> </ol>
</section> </section>`,
`,
}, },
t, t,
) )
@ -123,20 +122,19 @@ Another one.[^2]
[^2]: Another footnote. [^2]: Another footnote.
`, `,
Expected: `<p>That's some text with a footnote.<sup id="article12-fnref:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p> Expected: `<p>That's some text with a footnote.<sup id="article12-fnref:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p>
<p>Same footnote.<sup id="article12-fnref:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p> <p>Same footnote.<sup id="article12-fnref1:1"><a href="#article12-fn:1" class="link-class" title="link-title-2-1" role="doc-noteref">1</a></sup></p>
<p>Another one.<sup id="article12-fnref:2"><a href="#article12-fn:2" class="link-class" title="link-title-1-2" role="doc-noteref">2</a></sup></p> <p>Another one.<sup id="article12-fnref:2"><a href="#article12-fn:2" class="link-class" title="link-title-1-2" role="doc-noteref">2</a></sup></p>
<section class="footnotes" role="doc-endnotes"> <section class="footnotes" role="doc-endnotes">
<hr> <hr>
<ol> <ol>
<li id="article12-fn:1" role="doc-endnote"> <li id="article12-fn:1" role="doc-endnote">
<p>And that's the footnote.&#160;<a href="#article12-fnref:1" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p> <p>And that's the footnote.&#160;<a href="#article12-fnref:1" class="backlink-class" title="backlink-title" role="doc-backlink">^</a>&#160;<a href="#article12-fnref1:1" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p>
</li> </li>
<li id="article12-fn:2" role="doc-endnote"> <li id="article12-fn:2" role="doc-endnote">
<p>Another footnote.&#160;<a href="#article12-fnref:2" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p> <p>Another footnote.&#160;<a href="#article12-fnref:2" class="backlink-class" title="backlink-title" role="doc-backlink">^</a></p>
</li> </li>
</ol> </ol>
</section> </section>`,
`,
}, },
t, t,
) )