Turning empty link definitions into anchors

Currently CommonMark doesn’t allow reference link definitions without a target:

[foo]:

[foo]

In this respect it is in line with most implementations, though a few treat this as a link with an empty URL.

This seems a waste of good syntx. What if an empty reference definition were given a special meaning as an anchor, as illustrated by the following (which would have been really handy in writing the spec document):

[link text]:

The link text cannot contain links, though it may
contain images.  Etc.

... later ...

See the discussion of [link text], above.

where this gets converted to:

<a id="link-text"></a>

<p>The link text cannot contain links, though it may
contain images.  Etc.</p>

... later ...

<p>See the discussion of <a href="#link-text">link text</a>, above.</p>
4 Likes

The one little problem to consider with the very clean syntax is that what if the writer wrote the empty link as a header to a list:

[Pets]:
1. cat
2. dog

[Pets]: http://wikipedia/pets

I think it’s an interesting idea. However, I find the <a id="link-text"></a> without content, without href and outside any paragraph, a bit strange. A bit better to use <span id="link-text"></span>.

But personally, I find the proposed span-syntax more natural anyway (which could default to generating an id if no attributes are provided):

The [link text]{} cannot contain links, though it may
contain images.  Etc.

... later ...

See the discussion of [link text], above.

Or even an attribute on the entire paragraph:

The link text cannot contain links, though it may
contain images.  Etc.
{#link-text}

... later ...

See the discussion of [link text], above.

I don’t see the harm in doing this. Seems compatible, and useful.

For the record, the “correct” HTML5 way to link to an anchor is by the id attribute of an existing HTML element; adding an arbitrary empty link is not ideal.

It is not wrong, though.

I thought maybe we could insert an anchor element in the AST, and render it in HTML by adding the id to the following block element. But I suppose this wouldn’t work when you have multiple anchor definitions, as would be useful in a paragraph that defines several terms:

[link text]:
[link label]:

We distinguish here between the link
text and the link label....

I take @Knagis’s point about the potential for giving unexpected results in that list case. But I don’t know if such cases are common enough to make this syntax worth avoiding. Note that you’d still be able to do:

[Pets][]:
- dog
- cat

That’s funny, because the a is for “anchor”, although it originally was used with the name attribute exclusively.

I think this proposal would do little to no harm for vanilla Markdown, but it may be less backwards compatible with some definition list extensions. I would actually prefer a way to (implicitly) mark definitions <dfn> etc. that would become link targets automatically (besides headings and captions).

Another, related question, do empty-text links have any special semantics or should they acquire some meaning?

[][reference]
[](address)

It’s tough to think of any use for a link with no text; on the other hand, people do sometimes use images with no alt attribute (though they shouldn’t), and we should keep the connection between image and link syntaxes.

But it is tempting to give some real purpose to these otherwise useless elements, making them a syntax for anchors, perhaps.

1 Like

We get a surprising number of requests for anchor elements. It comes up a fair bit.

Note, that allowing arbitrary id/name (without forced prefix/postfix) is a security hole (search “dom clobbering”).

1 Like

GitHub’s solution to dom clobbering is interesting: User-generated content and DOM clobbering - Brandon Keepers

Also, I posted some thoughts about scoping IDs to particular sections of a page, over in the automatic header IDs topic. Relevant here, I think? I will paste the comment for convenience:

Really? Can you elaborate? To me, this sounds like people that know of the legacy <a name="my-anchor"></a> syntax and don’t know they could just jump to any element with an id. Why would you introduce extra a-elements if you could just add an id to a semantically meaningful existing element in your HTML?

right now are we set with the attribute support? []{#id} isn’t that terrible.

2 Likes

Overall, this idea is seen favorable upon. Maybe, however, we should really ask a related, more general question:

Should link reference definitions completely vanish?

Mainly to support extensions (e.g. for footnotes, abbreviations, definitions/glossaries, bibliographies), I believe they should be kept at least in the AST and perhaps even invisibly in HTML output:

[foo]: foo
[bar]: <>
[baz]: "baz"
[quuz]: 
.
<a id="foo" href="foo"></a>
<a id="bar" href=""></a>
<a id="baz" title="baz"></a>
<a id="quuz"></a>

The example does not address the problem of DOM clobbering mentioned before.

Related