Update MD054/link-image-style to add url_inline parameter (fixes #753).

This commit is contained in:
David Anson 2023-11-12 22:42:02 -08:00
parent 84333a5f08
commit b709a2f624
26 changed files with 347 additions and 39 deletions

View file

@ -5,8 +5,9 @@ atx
ATX
atx_closed
ATX-style
Autolinks
autolink
autolinks
Autolinks
axibase
backtick
backticks
@ -15,18 +16,18 @@ blockquotes
Boostnote
br
br_spaces
Changelog
Changelogs
changelog
Changelog
changelogs
Changelogs
CLI
coc-markdownlint
CodeQL
CodiMD
CommonMark
config
config.
Config
config.
CVE-\d+-\d+
docs-util
ES2015
@ -76,19 +77,19 @@ npm
ol
ol_multi
ol-prefix
Pandoc
pandoc
Pandoc
Params
parsers
pre-commit
Reactable
README
Reimplement
reimplement
Reimplement
setext
setext-style
setext_with_atx
setext_with_atx_closed
setext-style
single-h1
sublist
Super-Linter
@ -97,8 +98,8 @@ TOML
trimLeft
trimRight
ul
ul-indent
ul_single
ul-indent
ul-start-left
ul-style
unhandled

View file

@ -6636,7 +6636,8 @@ module.exports = {
var full = config.full === undefined || !!config.full;
var collapsed = config.collapsed === undefined || !!config.collapsed;
var shortcut = config.shortcut === undefined || !!config.shortcut;
if (autolink && inline && full && collapsed && shortcut) {
var urlInline = config.url_inline === undefined || !!config.url_inline;
if (autolink && inline && full && collapsed && shortcut && urlInline) {
// Everything allowed, nothing to check
return;
}
@ -6671,7 +6672,8 @@ module.exports = {
destination = getTokenTextByType(descendents, "resourceDestinationString");
if (destination) {
// link kind is an inline link
isError = !inline;
var title = getTokenTextByType(descendents, "resourceTitleString");
isError = !inline || !urlInline && autolink && !title && !image;
} else {
// link kind is a full/collapsed/shortcut reference link
var isShortcut = !children.some(function (t) {
@ -6690,13 +6692,16 @@ module.exports = {
if (startLine === endLine) {
range = [startColumn, endColumn - startColumn];
var insertText = null;
if (inline && label) {
var canInline = inline && label;
var canAutolink = autolink && !image && autolinkAble(destination);
if (canInline && (urlInline || !canAutolink)) {
// Most useful form
var prefix = image ? "!" : "";
// @ts-ignore
var escapedLabel = label.replace(/[[\]]/g, "\\$&");
var escapedDestination = destination.replace(/[()]/g, "\\$&");
insertText = "".concat(prefix, "[").concat(escapedLabel, "](").concat(escapedDestination, ")");
} else if (autolink && !image && autolinkAble(destination)) {
} else if (canAutolink) {
// Simplest form
insertText = "<".concat(removeBackslashEscapes(destination), ">");
}

View file

@ -60,6 +60,20 @@ This rule does *not* fix scenarios that require converting a link or image to
the `full`, `collapsed`, or `shortcut` reference styles because that involves
naming the reference and determining where to insert it in the document.
Setting the `url_inline` parameter to `false` prevents the use of inline links
with the same absolute URL text/destination and no title because such links can
be converted to autolinks:
```markdown
[https://example.com](https://example.com)
```
To fix `url_inline` violations, use the simpler autolink syntax instead:
```markdown
<https://example.com>
```
Rationale: Consistent formatting makes it easier to understand a document.
Autolinks are concise, but appear as URLs which can be long and confusing.
Inline links and images can include descriptive text, but take up more space in

View file

@ -2240,6 +2240,7 @@ Parameters:
- `inline`: Allow inline links and images (`boolean`, default `true`)
- `shortcut`: Allow shortcut reference links and images (`boolean`, default
`true`)
- `url_inline`: Allow URLs as inline links (`boolean`, default `true`)
Fixable: Some violations can be fixed by tooling
@ -2305,6 +2306,20 @@ This rule does *not* fix scenarios that require converting a link or image to
the `full`, `collapsed`, or `shortcut` reference styles because that involves
naming the reference and determining where to insert it in the document.
Setting the `url_inline` parameter to `false` prevents the use of inline links
with the same absolute URL text/destination and no title because such links can
be converted to autolinks:
```markdown
[https://example.com](https://example.com)
```
To fix `url_inline` violations, use the simpler autolink syntax instead:
```markdown
<https://example.com>
```
Rationale: Consistent formatting makes it easier to understand a document.
Autolinks are concise, but appear as URLs which can be long and confusing.
Inline links and images can include descriptive text, but take up more space in

View file

@ -13,6 +13,7 @@ Parameters:
- `inline`: Allow inline links and images (`boolean`, default `true`)
- `shortcut`: Allow shortcut reference links and images (`boolean`, default
`true`)
- `url_inline`: Allow URLs as inline links (`boolean`, default `true`)
Fixable: Some violations can be fixed by tooling
@ -78,6 +79,20 @@ This rule does *not* fix scenarios that require converting a link or image to
the `full`, `collapsed`, or `shortcut` reference styles because that involves
naming the reference and determining where to insert it in the document.
Setting the `url_inline` parameter to `false` prevents the use of inline links
with the same absolute URL text/destination and no title because such links can
be converted to autolinks:
```markdown
[https://example.com](https://example.com)
```
To fix `url_inline` violations, use the simpler autolink syntax instead:
```markdown
<https://example.com>
```
Rationale: Consistent formatting makes it easier to understand a document.
Autolinks are concise, but appear as URLs which can be long and confusing.
Inline links and images can include descriptive text, but take up more space in

View file

@ -1020,6 +1020,10 @@ export interface Configuration {
* Allow shortcut reference links and images
*/
shortcut?: boolean;
/**
* Allow URLs as inline links
*/
url_inline?: boolean;
};
/**
* MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md054.md
@ -1047,6 +1051,10 @@ export interface Configuration {
* Allow shortcut reference links and images
*/
shortcut?: boolean;
/**
* Allow URLs as inline links
*/
url_inline?: boolean;
};
/**
* headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043

View file

@ -32,7 +32,8 @@ module.exports = {
const full = (config.full === undefined) || !!config.full;
const collapsed = (config.collapsed === undefined) || !!config.collapsed;
const shortcut = (config.shortcut === undefined) || !!config.shortcut;
if (autolink && inline && full && collapsed && shortcut) {
const urlInline = (config.url_inline === undefined) || !!config.url_inline;
if (autolink && inline && full && collapsed && shortcut && urlInline) {
// Everything allowed, nothing to check
return;
}
@ -62,7 +63,8 @@ module.exports = {
getTokenTextByType(descendents, "resourceDestinationString");
if (destination) {
// link kind is an inline link
isError = !inline;
const title = getTokenTextByType(descendents, "resourceTitleString");
isError = !inline || (!urlInline && autolink && !title && !image);
} else {
// link kind is a full/collapsed/shortcut reference link
const isShortcut = !children.some((t) => t.type === "reference");
@ -80,13 +82,16 @@ module.exports = {
if (startLine === endLine) {
range = [ startColumn, endColumn - startColumn ];
let insertText = null;
if (inline && label) {
const canInline = (inline && label);
const canAutolink = (autolink && !image && autolinkAble(destination));
if (canInline && (urlInline || !canAutolink)) {
// Most useful form
const prefix = (image ? "!" : "");
// @ts-ignore
const escapedLabel = label.replace(/[[\]]/g, "\\$&");
const escapedDestination = destination.replace(/[()]/g, "\\$&");
insertText = `${prefix}[${escapedLabel}](${escapedDestination})`;
} else if (autolink && !image && autolinkAble(destination)) {
} else if (canAutolink) {
// Simplest form
insertText = `<${removeBackslashEscapes(destination)}>`;
}

View file

@ -290,6 +290,8 @@
// Allow collapsed reference links and images
"collapsed": true,
// Allow shortcut reference links and images
"shortcut": true
"shortcut": true,
// Allow URLs as inline links
"url_inline": true
}
}

View file

@ -262,3 +262,5 @@ MD054:
collapsed: true
# Allow shortcut reference links and images
shortcut: true
# Allow URLs as inline links
url_inline: true

View file

@ -523,7 +523,12 @@ for (const rule of rules) {
"description": "Allow shortcut reference links and images",
"type": "boolean",
"default": true
}
},
"url_inline": {
"description": "Allow URLs as inline links",
"type": "boolean",
"default": true
},
};
break;
default:

View file

@ -1587,6 +1587,11 @@
"description": "Allow shortcut reference links and images",
"type": "boolean",
"default": true
},
"url_inline": {
"description": "Allow URLs as inline links",
"type": "boolean",
"default": true
}
},
"additionalProperties": false
@ -1623,6 +1628,11 @@
"description": "Allow shortcut reference links and images",
"type": "boolean",
"default": true
},
"url_inline": {
"description": "Allow URLs as inline links",
"type": "boolean",
"default": true
}
},
"additionalProperties": false

View file

@ -1,4 +1,4 @@
# Link Style autolink_only
# Link Style Autolink Only
Text [url](https://example.com) text {MD054}

View file

@ -1,4 +1,4 @@
# Link Style autolink_or_inline
# Link Style Autolink or Inline
Text [url](https://example.com) text

View file

@ -1,4 +1,4 @@
# Link Style autolink_or_reference
# Link Style Autolink or Reference
Text [url](https://example.com) text {MD054}

View file

@ -1,4 +1,4 @@
# Link Style reference_only
# Link Style Collapsed Only
Text [url](https://example.com) text {MD054}

View file

@ -1,4 +1,4 @@
# Link Style reference_only
# Link Style Full Only
Text [url](https://example.com) text {MD054}

View file

@ -1,4 +1,4 @@
# Link Style inline_only
# Link Style Inline Only
Text [url](https://example.com) text

View file

@ -1,4 +1,4 @@
# Link Style inline_or_reference
# Link Style Inline or Reference
Text [url](https://example.com) text

View file

@ -0,0 +1,37 @@
# Link Style No URL Inline Not Possible
Text [https://example.com](https://example.com) text
Text ![https://example.com](https://example.com) text
Text [https://example.com](<https://example.com>) text
Text ![https://example.com](<https://example.com>) text
Text [https://example.com](https://example.com/page "title") text
Text ![https://example.com](https://example.com/page "title") text
Text [https://example.com](https://example.com "title") text
Text ![https://example.com](https://example.com "title") text
Text [https://example.com][url] text
Text ![https://example.com][url] text
Text [https://example.com][url-title] text
Text ![https://example.com][url-title] text
Text <https://example.com> text {MD054}
[url]: https://example.com
[url-title]: https://example.com "title"
<!-- markdownlint-configure-file {
"link-image-style": {
"autolink": false,
"url_inline": false
}
} -->

View file

@ -0,0 +1,36 @@
# Link Style No URL Inline Possible
Text [https://example.com](https://example.com) text {MD054}
Text ![https://example.com](https://example.com) text
Text [https://example.com](<https://example.com>) text {MD054}
Text ![https://example.com](<https://example.com>) text
Text [https://example.com](https://example.com/page "title") text
Text ![https://example.com](https://example.com/page "title") text
Text [https://example.com](https://example.com "title") text
Text ![https://example.com](https://example.com "title") text
Text [https://example.com][url] text
Text ![https://example.com][url] text
Text [https://example.com][url-title] text
Text ![https://example.com][url-title] text
Text <https://example.com> text
[url]: https://example.com
[url-title]: https://example.com "title"
<!-- markdownlint-configure-file {
"link-image-style": {
"url_inline": false
}
} -->

View file

@ -1,4 +1,4 @@
# Link Style autolink_only
# Link Style None
Text [url](https://example.com) text {MD054}

View file

@ -1,4 +1,4 @@
# Link Style reference_only
# Link Style Reference Only
Text [url](https://example.com) text {MD054}

View file

@ -1,4 +1,4 @@
# Link Style reference_only
# Link Style Shortcut Only
Text [url](https://example.com) text {MD054}

View file

@ -915,7 +915,7 @@ test("readme", async(t) => {
});
test("validateJsonUsingConfigSchemaStrict", async(t) => {
t.plan(169);
t.plan(171);
const { addSchema, validate } =
await import("@hyperjump/json-schema/draft-07");
addSchema(configSchemaStrict, configSchemaStrictUri);

View file

@ -24749,7 +24749,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style autolink_only␊
fixed: `# Link Style Autolink Only␊
Text <https://example.com> text {MD054}␊
@ -24999,7 +24999,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style autolink_or_inline␊
fixed: `# Link Style Autolink or Inline␊
Text [url](https://example.com) text␊
@ -25386,7 +25386,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style autolink_or_reference␊
fixed: `# Link Style Autolink or Reference␊
Text <https://example.com> text {MD054}␊
@ -25898,7 +25898,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style reference_only␊
fixed: `# Link Style Collapsed Only␊
Text [url](https://example.com) text {MD054}␊
@ -26413,7 +26413,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style reference_only␊
fixed: `# Link Style Full Only␊
Text [url](https://example.com) text {MD054}␊
@ -26742,7 +26742,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style inline_only␊
fixed: `# Link Style Inline Only␊
Text [url](https://example.com) text␊
@ -26912,7 +26912,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style inline_or_reference␊
fixed: `# Link Style Inline or Reference␊
Text [url](https://example.com) text␊
@ -26991,6 +26991,159 @@ Generated by [AVA](https://avajs.dev).
`,
}
## link-style-no-url-inline-not-possible.md
> Snapshot 1
{
errors: [
{
errorContext: '<https://example.com>',
errorDetail: null,
errorRange: [
6,
21,
],
fixInfo: {
deleteCount: 21,
editColumn: 6,
insertText: '[https://example.com](https://example.com)',
},
lineNumber: 27,
ruleDescription: 'Link and image style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md054.md',
ruleNames: [
'MD054',
'link-image-style',
],
},
],
fixed: `# Link Style No URL Inline Not Possible␊
Text [https://example.com](https://example.com) text␊
Text ![https://example.com](https://example.com) text␊
Text [https://example.com](<https://example.com>) text␊
Text ![https://example.com](<https://example.com>) text␊
Text [https://example.com](https://example.com/page "title") text␊
Text ![https://example.com](https://example.com/page "title") text␊
Text [https://example.com](https://example.com "title") text␊
Text ![https://example.com](https://example.com "title") text␊
Text [https://example.com][url] text␊
Text ![https://example.com][url] text␊
Text [https://example.com][url-title] text␊
Text ![https://example.com][url-title] text␊
Text [https://example.com](https://example.com) text {MD054}␊
[url]: https://example.com␊
[url-title]: https://example.com "title"␊
<!-- markdownlint-configure-file {␊
"link-image-style": {␊
"autolink": false,␊
"url_inline": false␊
}␊
} -->␊
`,
}
## link-style-no-url-inline-possible.md
> Snapshot 1
{
errors: [
{
errorContext: '[https://example.com](https://...',
errorDetail: null,
errorRange: [
6,
42,
],
fixInfo: {
deleteCount: 42,
editColumn: 6,
insertText: '<https://example.com>',
},
lineNumber: 3,
ruleDescription: 'Link and image style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md054.md',
ruleNames: [
'MD054',
'link-image-style',
],
},
{
errorContext: '[https://example.com](<https:/...',
errorDetail: null,
errorRange: [
6,
44,
],
fixInfo: {
deleteCount: 44,
editColumn: 6,
insertText: '<https://example.com>',
},
lineNumber: 7,
ruleDescription: 'Link and image style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md054.md',
ruleNames: [
'MD054',
'link-image-style',
],
},
],
fixed: `# Link Style No URL Inline Possible␊
Text <https://example.com> text {MD054}␊
Text ![https://example.com](https://example.com) text␊
Text <https://example.com> text {MD054}␊
Text ![https://example.com](<https://example.com>) text␊
Text [https://example.com](https://example.com/page "title") text␊
Text ![https://example.com](https://example.com/page "title") text␊
Text [https://example.com](https://example.com "title") text␊
Text ![https://example.com](https://example.com "title") text␊
Text [https://example.com][url] text␊
Text ![https://example.com][url] text␊
Text [https://example.com][url-title] text␊
Text ![https://example.com][url-title] text␊
Text <https://example.com> text␊
[url]: https://example.com␊
[url-title]: https://example.com "title"␊
<!-- markdownlint-configure-file {␊
"link-image-style": {␊
"url_inline": false␊
}␊
} -->␊
`,
}
## link-style-none.md
> Snapshot 1
@ -27456,7 +27609,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style autolink_only
fixed: `# Link Style None
Text [url](https://example.com) text {MD054}␊
@ -27877,7 +28030,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style reference_only␊
fixed: `# Link Style Reference Only␊
Text [url](https://example.com) text {MD054}␊
@ -28358,7 +28511,7 @@ Generated by [AVA](https://avajs.dev).
],
},
],
fixed: `# Link Style reference_only␊
fixed: `# Link Style Shortcut Only␊
Text [url](https://example.com) text {MD054}␊