Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precedence of link within link #193

Open
Knagis opened this issue Nov 10, 2014 · 15 comments
Open

Precedence of link within link #193

Knagis opened this issue Nov 10, 2014 · 15 comments
Labels
Milestone

Comments

@Knagis
Copy link
Contributor

Knagis commented Nov 10, 2014

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.

@Knagis
Copy link
Contributor Author

Knagis commented Nov 10, 2014

Furthermore, there is an inconsistency between how links and images are handled:

Example 389:
[foo [bar](/uri)](/uri) ➡️ <p>[foo <a href="/uri">bar</a>](/uri)</p>

Example 436:
![foo ![bar](/url)](/url2) ➡️ <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.

@jgm jgm added the spec label Nov 17, 2014
@jgm
Copy link
Member

jgm commented Dec 26, 2014

@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"

@Knagis
Copy link
Contributor Author

Knagis commented Dec 26, 2014

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.

@Knagis
Copy link
Contributor Author

Knagis commented Dec 26, 2014

If that lone argument did not convince you, this issue can be closed - I will then adjust my parser accordingly.

@Knagis
Copy link
Contributor Author

Knagis commented Jan 17, 2015

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>

@jgm
Copy link
Member

jgm commented Jun 15, 2015

Commit #331 clarifies this in the spec, but I'm leaving this issue open, because I think it still needs rethinking.

@mity
Copy link

mity commented Jun 7, 2017

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.

See [<http://foo>](/url)

@mgeier
Copy link
Contributor

mgeier commented Jun 7, 2017

@adamhotep
Copy link

adamhotep commented Oct 18, 2022

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.

@vassudanagunta
Copy link

vassudanagunta commented Oct 21, 2022

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.

@adamhotep
Copy link

@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.

@masak
Copy link

masak commented Jan 20, 2023

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.

@vassudanagunta
Copy link

vassudanagunta commented Jan 20, 2023

Likewise HTML5:

Content model:
Transparent, but there must be no interactive content, a element descendant,...

See also Why are nested anchor tags illegal?.

@masak
Copy link

masak commented Jan 20, 2023

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. 😄

@vassudanagunta
Copy link

vassudanagunta commented Jan 20, 2023

[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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants