github/cmark-gfm

Footnotes in links are broken

wooorm opened this issue · 2 comments

[a [^b] c](https://example.com)

[^b]: asd

Renders (formatted w/ whitespace):

<p dir="auto">
  <a href="https://example.com">
    a
    <sup></sup>
  </a>
  <a
    href="#user-content-fn-b"
    id="user-content-fnref-b"
    data-footnote-ref=""
    aria-describedby="footnote-label"
  >1</a>
  c
</p>

Rendered here:

a 1 c


Expected. Either (when not using HTML parsing to sanitize):

<p>
  <a href="https://example.com">
    a
    <sup>
      <a
        href="#user-content-fn-b"
        id="user-content-fnref-b"
        data-footnote-ref=""
        aria-describedby="footnote-label"
      >1</a>
    </sup>
    c
  </a>
</p>

Or (when not generating footnotes in certain disallowed tags):

<p>
  <a href="https://example.com">
    a [^b] c
  </a>
</p>

Footnotes

  1. asd

You can't have nested anchor tags, so this one is on your browser.1

Footnotes

  1. if you examine the output in cmark-gfm, you'll find the library does in fact nest the links 😉.

Yes, it is invalid.

CommonMark/GFM enforces logic to prevent it: it doesn’t allow what could be a link, when occurring around a link.
This is not the case for images, because images are fine in link.
Given that footnotes calls are similar to link labels, and implemented in the same code, why not implement the existing logic for links, too?

cmark-gfm/src/inlines.c

Lines 1242 to 1257 in ef1cfcb

// Now, if we have a link, we also want to deactivate earlier link
// delimiters. (This code can be removed if we decide to allow links
// inside links.)
if (!is_image) {
opener = subj->last_bracket;
while (opener != NULL) {
if (!opener->image) {
if (!opener->active) {
break;
} else {
opener->active = false;
}
}
opener = opener->previous;
}
}

if (!opener->active) {