Skip to content

Commit

Permalink
Update MD053/link-image-reference-definitions to add ignored_definiti…
Browse files Browse the repository at this point in the history
…ons parameter (default to ["//"]) (fixes #545).
  • Loading branch information
DavidAnson committed Aug 3, 2022
1 parent 2c3e8c9 commit a6489ac
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 31 deletions.
15 changes: 10 additions & 5 deletions demo/markdownlint-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
}
}
Expand Down Expand Up @@ -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 = {
Expand All @@ -4736,16 +4737,20 @@ 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);
}
}
// 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);
}
}
}
};
Expand Down
15 changes: 13 additions & 2 deletions doc/Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion lib/md033.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]);
}
}
}
Expand Down
29 changes: 18 additions & 11 deletions lib/md053.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => (
Expand All @@ -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,
Expand All @@ -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
);
}
}
}
};
7 changes: 6 additions & 1 deletion schema/.markdownlint.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
"//"
]
}
}
6 changes: 5 additions & 1 deletion schema/.markdownlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
"//"
]
12 changes: 12 additions & 0 deletions schema/build-config-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 18 additions & 2 deletions schema/markdownlint-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion test/markdownlint-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions test/reference-links-and-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
13 changes: 13 additions & 0 deletions test/reference-links-ignored-definitions-empty.md
Original file line number Diff line number Diff line change
@@ -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": []
}
} -->
17 changes: 17 additions & 0 deletions test/reference-links-ignored-definitions.md
Original file line number Diff line number Diff line change
@@ -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"
]
}
} -->
Loading

0 comments on commit a6489ac

Please sign in to comment.