[GH-ISSUE #1472] Should MD050 apply to link labels? #691

Closed
opened 2026-03-03 01:29:07 +03:00 by kerem · 5 comments
Owner

Originally created by @lemeb on GitHub (Jan 21, 2025).
Original GitHub issue: https://github.com/DavidAnson/markdownlint/issues/1472

Hi :)

Issue

Consider this:

# Let's talk about Python internals

One important thing about Python are **dunder functions**.
They are special methods that you can define in your own classes to
emulate built-in types. For example, you can define a `__len__`
method to make your class compatible with the `len` function.

Here are links to the official Python documentation:

* [`__len__`](https://docs.python.org/3/reference/datamodel.html#object.__len__)
* [`__len__`][object.__len__]
* [`__call__`][object.__call__]

The last two bullet points are reference links to the Python documentation. Some documentation plugins enable the use of this shortened syntax.

If you run markdownlint, however, you get an error:

markdownlint-cli2 v0.17.2 (markdownlint v0.37.4)
Finding: text.md
Linting: 1 file(s)
Summary: 4 error(s)
text.md:11:22 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore]
text.md:11:27 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore]
text.md:12:23 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore]
text.md:12:29 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore]

Is this intended?

At first, looking at the CommonMark spec, I was under the impression that maybe it is by design that link labels are not supposed to have rich syntax.

But the CommonMark playground suggests otherwise (link to the example):

[foo][bar]  <!-- This works -->

[bar]: /url "title"

[foo2][**bar2**]  <!-- This also works -->

[**bar2**]: /url "title"

[foo3][__bar3__]  <!-- This also works -->

[__bar3__]: /url "title"

It might be a philosophical question: do you consider link references to be part of the document, and therefore subject to MD050 like the rest of the text? Or is it simply metadata that deserves to be ignored?

I would say the latter, especially since the CommonMark spec says:

Note that matching [link reference definitions] is performed on normalized strings, not parsed inline content

... But I might be wrong!

Alternatively, having a configuration option to ignore link labels would be great.

Thanks a lot :)

Originally created by @lemeb on GitHub (Jan 21, 2025). Original GitHub issue: https://github.com/DavidAnson/markdownlint/issues/1472 Hi :) ## Issue Consider this: ```md # Let's talk about Python internals One important thing about Python are **dunder functions**. They are special methods that you can define in your own classes to emulate built-in types. For example, you can define a `__len__` method to make your class compatible with the `len` function. Here are links to the official Python documentation: * [`__len__`](https://docs.python.org/3/reference/datamodel.html#object.__len__) * [`__len__`][object.__len__] * [`__call__`][object.__call__] ``` The last two bullet points are reference links to the Python documentation. Some [documentation plugins](https://mkdocstrings.github.io/usage/#cross-references-to-other-projects-inventories) enable the use of this shortened syntax. If you run `markdownlint`, however, you get an error: ```bash markdownlint-cli2 v0.17.2 (markdownlint v0.37.4) Finding: text.md Linting: 1 file(s) Summary: 4 error(s) text.md:11:22 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore] text.md:11:27 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore] text.md:12:23 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore] text.md:12:29 MD050/strong-style Strong style [Expected: asterisk; Actual: underscore] ``` ## Is this intended? At first, looking at the CommonMark spec, I was under the impression that maybe it is by design that [link labels](https://spec.commonmark.org/0.31.2/#link-label) are not supposed to have rich syntax. But the CommonMark playground suggests otherwise ([link to the example](https://spec.commonmark.org/dingus/?text=%5Bfoo%5D%5Bbar%5D%20%20%3C!--%20This%20works%20--%3E%0A%0A%5Bbar%5D%3A%20%2Furl%20%22title%22%0A%0A%5Bfoo2%5D%5B**bar2**%5D%20%20%3C!--%20This%20also%20works%20--%3E%0A%0A%5B**bar2**%5D%3A%20%2Furl%20%22title%22%0A%0A%5Bfoo3%5D%5B__bar3__%5D%20%20%3C!--%20This%20also%20works%20--%3E%0A%0A%5B__bar3__%5D%3A%20%2Furl%20%22title%22%0A)): ```md [foo][bar] <!-- This works --> [bar]: /url "title" [foo2][**bar2**] <!-- This also works --> [**bar2**]: /url "title" [foo3][__bar3__] <!-- This also works --> [__bar3__]: /url "title" ``` It might be a philosophical question: do you consider link references to be part of the document, and therefore subject to `MD050` like the rest of the text? Or is it simply metadata that deserves to be ignored? I would say the latter, especially since the [CommonMark spec says](https://spec.commonmark.org/0.31.2/#example-545): > Note that matching [link reference definitions] is performed on normalized strings, not parsed inline content ... But I might be wrong! Alternatively, having a configuration option to ignore link labels would be great. Thanks a lot :)
kerem 2026-03-03 01:29:07 +03:00
  • closed this issue
  • added the
    question
    label
Author
Owner

@DavidAnson commented on GitHub (Jan 21, 2025):

Thank you for the detailed report! From what I see here, I think you're right. It surprises me that the parser is flagging emphasis in this context, but I'll have a look tonight or tomorrow and fix this.

<!-- gh-comment-id:2605242259 --> @DavidAnson commented on GitHub (Jan 21, 2025): Thank you for the detailed report! From what I see here, I think you're right. It surprises me that the parser is flagging emphasis in this context, but I'll have a look tonight or tomorrow and fix this.
Author
Owner

@DavidAnson commented on GitHub (Jan 22, 2025):

Your example produces no violations when the link references you show are defined:

https://dlaa.me/markdownlint/#%25m%23%20Let's%20talk%20about%20Python%20internals%0A%0AHere%20are%20links%20to%20the%20official%20Python%20documentation%3A%0A%0A*%20%5B%60__len__%60%5D%5Bobject.len%5D%0A*%20%5B%60__call__%60%5D%5Bobject.call%5D%0A%0A%5Bobject.len%5D%3A%20https%3A%2F%2Fexample.com%2Flen%0A%5Bobject.call%5D%3A%20https%3A%2F%2Fexample.com%2Fcall%0A

So I claim the current behavior of the rule is correct and consistent with CommonMark behavior.

In order for YOUR scenario to lint cleanly WITHOUT defining the link references, this rule would need to guess your project is using MkDocs configured for mkdocstrings and infer the location of mkdocs.yml and parse it for imports and load the inventory file and parse that file and try to match the undefined link reference. That's all pretty far out of scope for how rules behave today, so I am not inclined to do so if that's what you're proposing.

<!-- gh-comment-id:2606249505 --> @DavidAnson commented on GitHub (Jan 22, 2025): Your example produces no violations when the link references you show are defined: https://dlaa.me/markdownlint/#%25m%23%20Let's%20talk%20about%20Python%20internals%0A%0AHere%20are%20links%20to%20the%20official%20Python%20documentation%3A%0A%0A*%20%5B%60__len__%60%5D%5Bobject.__len__%5D%0A*%20%5B%60__call__%60%5D%5Bobject.__call__%5D%0A%0A%5Bobject.__len__%5D%3A%20https%3A%2F%2Fexample.com%2Flen%0A%5Bobject.__call__%5D%3A%20https%3A%2F%2Fexample.com%2Fcall%0A So I claim the current behavior of the rule is correct and consistent with CommonMark behavior. In order for YOUR scenario to lint cleanly WITHOUT defining the link references, this rule would need to guess your project is using MkDocs configured for mkdocstrings and infer the location of `mkdocs.yml` and parse it for imports and load the inventory file and parse that file and try to match the undefined link reference. That's all pretty far out of scope for how rules behave today, so I am not inclined to do so if that's what you're proposing.
Author
Owner

@lemeb commented on GitHub (Feb 5, 2025):

Hey, sorry for the delayed response, I was off.

If I understand you correctly, you are essentially saying that mkdocstrings is doing an illegal dependency injection, and that two sets of brackets should be treated as a raw text according to the Markdown spec.

I agree with you that it's totally unreasonable to expected markdownlint to process the files accordingly and only then lint the file.

You could try to allow users to have link labels that don't have corresponding references, and parse them as link labels anyway. I'm not sure that this could be implemented in a custom rule, since this goes to the heart of parsing logic. But I might be wrong, and then again, might be out of scope anyway.

Thanks :)

<!-- gh-comment-id:2636904765 --> @lemeb commented on GitHub (Feb 5, 2025): Hey, sorry for the delayed response, I was off. If I understand you correctly, you are essentially saying that mkdocstrings is doing an illegal dependency injection, and that two sets of brackets should be treated as a raw text according to the Markdown spec. I agree with you that it's totally unreasonable to expected markdownlint to process the files accordingly and only then lint the file. You could try to allow users to have link labels that don't have corresponding references, and parse them as link labels anyway. I'm not sure that this could be implemented in a custom rule, since this goes to the heart of parsing logic. But I might be wrong, and then again, might be out of scope anyway. Thanks :)
Author
Owner

@DavidAnson commented on GitHub (Feb 5, 2025):

Per the specification, if a link reference does not resolve, then that thing is not a link and it is treated as normal content. You can verify this with the demo link I sent by removing either of the reference definitions at the bottom.

I don't want to tamper with parse behavior, so my recommendation is to selectively or completely disable the relevant rule or change the reference strings in your project to not to include emphasis characters. (It's OK if your syntax isn't recognized as a link, the problem is just that it also contains content that violates one of the rules.)

<!-- gh-comment-id:2637581884 --> @DavidAnson commented on GitHub (Feb 5, 2025): Per the specification, if a link reference does not resolve, then that thing is not a link and it is treated as normal content. You can verify this with the demo link I sent by removing either of the reference definitions at the bottom. I don't want to tamper with parse behavior, so my recommendation is to selectively or completely disable the relevant rule or change the reference strings in your project to not to include emphasis characters. (It's OK if your syntax isn't recognized as a link, the problem is just that it also contains content that violates one of the rules.)
Author
Owner

@lemeb commented on GitHub (Feb 5, 2025):

Yep, I understand you! Thanks for the time

<!-- gh-comment-id:2637688178 --> @lemeb commented on GitHub (Feb 5, 2025): Yep, I understand you! Thanks for the time
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/markdownlint#691
No description provided.