Update MD053/link-image-reference-definitions to add ignored_definitions parameter (default to ["//"]) (fixes #545).

This commit is contained in:
David Anson 2022-08-02 20:36:47 -07:00
parent 2c3e8c938b
commit a6489acd6b
14 changed files with 234 additions and 31 deletions

View file

@ -3658,7 +3658,7 @@ module.exports = {
if (!linkDestinationRe.test(prefix)) {
const unescaped = unescapeMarkdown(prefix + "<", "_");
if (!unescaped.endsWith("_")) {
addError(onError, lineIndex + 1, "Element: " + element, null, [match.index + 1, tag.length]);
addError(onError, lineIndex + 1, "Element: " + element, undefined, [match.index + 1, tag.length]);
}
}
}
@ -4727,7 +4727,8 @@ module.exports = {
"description": "Link and image reference definitions should be needed",
"tags": ["images", "links"],
"function": function MD053(params, onError) {
const { lines } = params;
const ignored = new Set(params.config.ignored_definitions || ["//"]);
const lines = params.lines;
const { references, shortcuts, definitions, duplicateDefinitions } = referenceLinkImageData();
const singleLineDefinition = (line) => (line.replace(linkReferenceDefinitionRe, "").trim().length > 0);
const deleteFixInfo = {
@ -4736,7 +4737,9 @@ module.exports = {
// Look for unused link references (unreferenced by any link/image)
for (const definition of definitions.entries()) {
const [label, lineIndex] = definition;
if (!references.has(label) && !shortcuts.has(label)) {
if (!ignored.has(label) &&
!references.has(label) &&
!shortcuts.has(label)) {
const line = lines[lineIndex];
addError(onError, lineIndex + 1, `Unused link or image reference definition: "${label}"`, ellipsify(line), [1, line.length], singleLineDefinition(line) ? deleteFixInfo : 0);
}
@ -4744,8 +4747,10 @@ module.exports = {
// Look for duplicate link references (defined more than once)
for (const duplicateDefinition of duplicateDefinitions) {
const [label, lineIndex] = duplicateDefinition;
const line = lines[lineIndex];
addError(onError, lineIndex + 1, `Duplicate link or image reference definition: "${label}"`, ellipsify(line), [1, line.length], singleLineDefinition(line) ? deleteFixInfo : 0);
if (!ignored.has(label)) {
const line = lines[lineIndex];
addError(onError, lineIndex + 1, `Duplicate link or image reference definition: "${label}"`, ellipsify(line), [1, line.length], singleLineDefinition(line) ? deleteFixInfo : 0);
}
}
}
};

View file

@ -1315,7 +1315,7 @@ To fix this, use 'pure' Markdown instead of including raw HTML:
# Markdown heading
```
Note: To allow specific HTML elements, use the 'allowed_elements' parameter.
Note: To allow specific HTML elements, use the `allowed_elements` parameter.
Rationale: Raw HTML is allowed in Markdown, but this rule is included for
those who want their documents to only include "pure" Markdown, or for those
@ -2075,6 +2075,8 @@ Tags: images, links
Aliases: link-image-reference-definitions
Parameters: ignored_definitions (array of string; default [ "//" ])
Fixable: Most violations can be fixed by tooling
Links and images in Markdown can provide the link destination or image source
@ -2092,9 +2094,18 @@ unnecessary:
used and the others can be deleted.
This rule considers a reference definition to be used if any link or image
reference has the corresponding label. "Full", "collapsed", and "shortcut"
reference has the corresponding label. The "full", "collapsed", and "shortcut"
formats are all supported.
If there are reference definitions that are deliberately unreferenced, they can
be ignored by setting the `ignored_definitions` parameter. The default value of
this parameter ignores the following convention for adding non-HTML comments to
Markdown:
```md
[//]: # (This behaves like a comment)
```
<!-- markdownlint-configure-file {
"no-inline-html": {
"allowed_elements": [

View file

@ -38,7 +38,7 @@ module.exports = {
const unescaped = unescapeMarkdown(prefix + "<", "_");
if (!unescaped.endsWith("_")) {
addError(onError, lineIndex + 1, "Element: " + element,
null, [ match.index + 1, tag.length ]);
undefined, [ match.index + 1, tag.length ]);
}
}
}

View file

@ -11,7 +11,8 @@ module.exports = {
"description": "Link and image reference definitions should be needed",
"tags": [ "images", "links" ],
"function": function MD053(params, onError) {
const { lines } = params;
const ignored = new Set(params.config.ignored_definitions || [ "//" ]);
const lines = params.lines;
const { references, shortcuts, definitions, duplicateDefinitions } =
referenceLinkImageData();
const singleLineDefinition = (line) => (
@ -23,7 +24,11 @@ module.exports = {
// Look for unused link references (unreferenced by any link/image)
for (const definition of definitions.entries()) {
const [ label, lineIndex ] = definition;
if (!references.has(label) && !shortcuts.has(label)) {
if (
!ignored.has(label) &&
!references.has(label) &&
!shortcuts.has(label)
) {
const line = lines[lineIndex];
addError(
onError,
@ -38,15 +43,17 @@ module.exports = {
// Look for duplicate link references (defined more than once)
for (const duplicateDefinition of duplicateDefinitions) {
const [ label, lineIndex ] = duplicateDefinition;
const line = lines[lineIndex];
addError(
onError,
lineIndex + 1,
`Duplicate link or image reference definition: "${label}"`,
ellipsify(line),
[ 1, line.length ],
singleLineDefinition(line) ? deleteFixInfo : 0
);
if (!ignored.has(label)) {
const line = lines[lineIndex];
addError(
onError,
lineIndex + 1,
`Duplicate link or image reference definition: "${label}"`,
ellipsify(line),
[ 1, line.length ],
singleLineDefinition(line) ? deleteFixInfo : 0
);
}
}
}
};

View file

@ -275,5 +275,10 @@
"MD052": true,
// MD053/link-image-reference-definitions - Link and image reference definitions should be needed
"MD053": true
"MD053": {
// Ignored definitions
"ignored_definitions": [
"//"
]
}
}

View file

@ -249,4 +249,8 @@ MD051: true
MD052: true
# MD053/link-image-reference-definitions - Link and image reference definitions should be needed
MD053: true
MD053:
# Ignored definitions
ignored_definitions: [
"//"
]

View file

@ -463,6 +463,18 @@ for (const rule of rules) {
}
};
break;
case "MD053":
scheme.properties = {
"ignored_definitions": {
"description": "Ignored definitions",
"type": "array",
"items": {
"type": "string"
},
"default": [ "//" ]
}
};
break;
default:
custom = false;
break;

View file

@ -909,8 +909,24 @@
},
"MD053": {
"description": "MD053/link-image-reference-definitions - Link and image reference definitions should be needed",
"type": "boolean",
"default": true
"type": [
"boolean",
"object"
],
"default": true,
"properties": {
"ignored_definitions": {
"description": "Ignored definitions",
"type": "array",
"items": {
"type": "string"
},
"default": [
"//"
]
}
},
"additionalProperties": false
},
"link-image-reference-definitions": {
"$ref": "#/properties/MD053"

View file

@ -921,7 +921,7 @@ test("readme", (t) => new Promise((resolve) => {
}));
test("rules", (t) => new Promise((resolve) => {
t.plan(373);
t.plan(374);
fs.readFile("doc/Rules.md", "utf8",
(err, contents) => {
t.falsy(err);

View file

@ -166,6 +166,12 @@ https://example.com/multi-line-label
[unique6]: https://example.com/unique6
[unique7]: https://example.com/unique7
## Ignored Labels
[//]: # (This is a technique for putting comments in Markdown)
[//]: <> (Here is another variant)
## Invalid Labels
Duplicate:

View file

@ -0,0 +1,13 @@
# Reference Links Ignored Definitions (Empty)
Used reference link: [label]
[label]: https://example.com/label
[oops]: https://example.com/{MD053}
[//]: <> ({MD053})
<!-- markdownlint-configure-file {
"link-image-reference-definitions": {
"ignored_definitions": []
}
} -->

View file

@ -0,0 +1,17 @@
# Reference Links Ignored Definitions
Used reference link: [label]
[label]: https://example.com/label
[oops]: https://example.com/{MD053}
[okay]: https://example.com/ignored
[yep]: https://example.com/ignored
<!-- markdownlint-configure-file {
"link-image-reference-definitions": {
"ignored_definitions": [
"okay",
"yep"
]
}
} -->

View file

@ -33768,7 +33768,7 @@ Generated by [AVA](https://avajs.dev).
25,
],
fixInfo: null,
lineNumber: 196,
lineNumber: 202,
ruleDescription: 'Reference links and images should use a label that is defined',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md052',
ruleNames: [
@ -33784,7 +33784,7 @@ Generated by [AVA](https://avajs.dev).
10,
],
fixInfo: null,
lineNumber: 210,
lineNumber: 216,
ruleDescription: 'Reference links and images should use a label that is defined',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md052',
ruleNames: [
@ -33802,7 +33802,7 @@ Generated by [AVA](https://avajs.dev).
fixInfo: {
deleteCount: -1,
},
lineNumber: 172,
lineNumber: 178,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
@ -33820,7 +33820,7 @@ Generated by [AVA](https://avajs.dev).
fixInfo: {
deleteCount: -1,
},
lineNumber: 175,
lineNumber: 181,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
@ -33838,7 +33838,7 @@ Generated by [AVA](https://avajs.dev).
fixInfo: {
deleteCount: -1,
},
lineNumber: 178,
lineNumber: 184,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
@ -33854,7 +33854,7 @@ Generated by [AVA](https://avajs.dev).
44,
],
fixInfo: null,
lineNumber: 180,
lineNumber: 186,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
@ -33870,7 +33870,7 @@ Generated by [AVA](https://avajs.dev).
44,
],
fixInfo: null,
lineNumber: 183,
lineNumber: 189,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
@ -34047,6 +34047,12 @@ Generated by [AVA](https://avajs.dev).
[unique6]: https://example.com/unique6␊
[unique7]: https://example.com/unique7␊
## Ignored Labels␊
[//]: # (This is a technique for putting comments in Markdown)␊
[//]: <> (Here is another variant)␊
## Invalid Labels␊
Duplicate:␊
@ -34089,6 +34095,107 @@ Generated by [AVA](https://avajs.dev).
`,
}
## reference-links-ignored-definitions-empty.md
> Snapshot 1
{
errors: [
{
errorContext: '[oops]: https://example.com/{M...',
errorDetail: 'Unused link or image reference definition: "oops"',
errorRange: [
1,
35,
],
fixInfo: {
deleteCount: -1,
},
lineNumber: 6,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
'MD053',
'link-image-reference-definitions',
],
},
{
errorContext: '[//]: <> ({MD053})',
errorDetail: 'Unused link or image reference definition: "//"',
errorRange: [
1,
18,
],
fixInfo: {
deleteCount: -1,
},
lineNumber: 7,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
'MD053',
'link-image-reference-definitions',
],
},
],
fixed: `# Reference Links Ignored Definitions (Empty)␊
Used reference link: [label]␊
[label]: https://example.com/label␊
<!-- markdownlint-configure-file {␊
"link-image-reference-definitions": {␊
"ignored_definitions": []␊
}␊
} -->␊
`,
}
## reference-links-ignored-definitions.md
> Snapshot 1
{
errors: [
{
errorContext: '[oops]: https://example.com/{M...',
errorDetail: 'Unused link or image reference definition: "oops"',
errorRange: [
1,
35,
],
fixInfo: {
deleteCount: -1,
},
lineNumber: 6,
ruleDescription: 'Link and image reference definitions should be needed',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md053',
ruleNames: [
'MD053',
'link-image-reference-definitions',
],
},
],
fixed: `# Reference Links Ignored Definitions␊
Used reference link: [label]␊
[label]: https://example.com/label␊
[okay]: https://example.com/ignored␊
[yep]: https://example.com/ignored␊
<!-- markdownlint-configure-file {␊
"link-image-reference-definitions": {␊
"ignored_definitions": [␊
"okay",␊
"yep"␊
]␊
}␊
} -->␊
`,
}
## required-headings-all-optional-at-least-one.md
> Snapshot 1