Open Knagis opened 10 years ago
Furthermore, there is an inconsistency between how links and images are handled:
Example 389:
[foo [bar](/uri)](/uri)
:arrow_right: <p>[foo <a href="/uri">bar</a>](/uri)</p>
Example 436:
![foo ![bar](/url)](/url2)
:arrow_right: <p><img src="/url2" alt="foo bar" /></p>
My opinion is that there should be no difference between nested images and links in these cases.
@Knagis - I don't think this is an inconsistency. There's an important difference between the two cases. Links are not allowed in the link text of a link, but they are allowed in the image description. The difference is obscured a bit by the fact that links are not rendered as links inside an alt
attribute, but see the AST output:
% ./cmark -t ast
[foo [bar](/uri)](/uri)
paragraph
text "["
text "foo "
link url="/uri"
text "bar"
text "]"
text "(/uri)"
% ./cmark -t ast
![foo ![bar](/url)](/url2)
paragraph
image url="/url2"
text "foo "
image url="/url"
text "bar"
For me it feels that these similar looking cases should act the same in terms of which - inner or outer - link/image takes precedence (but that is just a visual thing by looking at these two cases). And for links the same approach as with images would be used - the contents of the link are parsed as is in the AST but rendered without the nested link. So the output for 389 would be <a href="/uri">foo bar</a>
.
The only practical benefit though for this approach (apart from the test cases looking nicer together) is that an application could walk the AST and issue a warning that the link-within-link is not a valid construct. If the parser creates text nodes, this cannot be done.
If that lone argument did not convince you, this issue can be closed - I will then adjust my parser accordingly.
Looking at the github commits I just realized a rather good example how links within links could be used if the renderer decides to support it:
[Fixed [#285](/issues/285) in cmark](/commits/12345)
<a href="/commits/12345">Fixed </a><a href="/issues/285">#285</a><a href="/commits/12345"> in cmark</a>
Commit #331 clarifies this in the spec, but I'm leaving this issue open, because I think it still needs rethinking.
Also note there is yet another inconsistency: While links cannot be nested in each other, an autolink on the other side is allowed to be nested in the link text.
There is some additional discussion in https://talk.commonmark.org/t/why-is-link-text-not-allowed-to-contain-other-links/2434.
For reference, it looks like HTML rendering on this concept is unclear too. Browsers choose to deal with this in a different manner.
[foo [bar](/bar) foo](/foo)
would intuitively translate into:
<a href="/foo">foo <a href="/bar">bar</a> foo</a>
I expected this to give me foo bar foo
in which clicking the word "bar" goes to /bar
and clicking either word "foo", or the spaces around "bar", would go to /foo
. However, Firefox and Chromium both terminate the first link at the beginning of the second one (the second foo
is plain text).
Here's a paste from the DOM inspector's console output for console.log(document.body.innerHTML)
:
<a href="/foo">foo </a><a href="/bar">bar</a> foo
(I'm not going to dig through the HTML specs to see if this is explicitly defined or if it's ambiguous and Google & Mozilla merely decided to do the same as each other, especially since one goal of CommonMark is to be independent from HTML. That doesn't mean we can't learn from HTML's decisions.)
One easy solution would simply be to pass the buck: defer to the browser and offer nested <a>
tags. A related (and more HTML-independent) alternative would be to terminate the first link at the start of the second link, reproducing the web browser decision.
Link nesting simply does not make sense semantically, so why should it be supported syntactically?
Case in point, how often, if ever do you see
<a href="/foo">foo <a href="/bar">bar</a> foo</a>
in the wild? Firefox and Chromium behaviors are more likely 🤷🏾♂️ ways of dealing with tag soup than an expression of "Oh yeah, this makes sense, and here is the natural interpretation."
In other words, no "solution" is needed.
@vassudanagunta: I see this as semantically reasonable. The inner link overrides the outer link. Think about it like colors:
<span style="color:red">red <span style="color:orange">orange</span> red</span>
We don't ask "where did the red go" because we know it's merely underneath the orange. This is consistent with putting an image among text in markdown:
[foo ![image of foo](foo.png) foo](foo.html)
The text is blue and underlined while the image in the middle of it is not.
For what it's worth, HTML 4.01 says no.
12.2.2 Nested links are illegal
Links and anchors defined by the A element must not be nested; an A element must not contain any other A elements.
(But I agree it has an obvious semantics regardless.
Content model: Transparent, but there must be no interactive content, a element descendant,...
See also Why are nested anchor tags illegal?.
The stackoverflow answer makes the case that anchors were designed to be "point-like", which explains why HTML 4.01 and HTML5 both rule out nested a
elements.
Intuitively, I agree with @adamhotep 's explanation above. But I must admit that HTML 4.01 and HTML5 don't seem to share that intuition, because they consider anchors to be point-like and simple.
I also liked @Knagis 's provided example:
[Fixed [#285](/issues/285) in cmark](/commits/12345)
There's no hesitation when I read that about what that "means", or how I would expect it to look rendered in a browser. I saw that example before I saw HTML 4.01's prohibition against nested a
elements; it made sense to me before, and it still makes sense to me after.
The output @Knagis suggests doesn't violate a
nesting:
<a href="/commits/12345">Fixed </a><a href="/issues/285">#285</a><a href="/commits/12345"> in cmark</a>
But I suppose it could be an argument for either (a) how to render nested Markdown link syntax without violating HTML's interdictions, or (b) how cumbersome/roundabout it would be to render nested Markdown links into conformant HTML, so we'd better not. :smile:
[Fixed [#285](/issues/285) in cmark](/commits/12345)
Sure it's clear what it means upon examination but it's really bad for readers. To me it's akin to a button within a button, but worse because it's even harder to see in text unless you start making text look like buttons.
I'm not saying that a markup language should be designed to prevent writers from shooting themselves in the foot, but I am saying why bend over backwards to give them a foot gun?
Example 389 shows what happens when a link is nested within a link - the inner link is rendered. But I can't find the rule describing this - probably a statement similar to the emphasis rule (closed-first and opened last) should be added.