Update MD051/link-fragments to handle backslash-escaped content in link and definition destinations (fixes #956).

This commit is contained in:
David Anson 2023-09-06 21:25:00 -07:00
parent 1ddee6b195
commit ba260b9b1e
5 changed files with 81 additions and 28 deletions

File diff suppressed because one or more lines are too long

View file

@ -15,11 +15,15 @@ const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
const childrenExclude = new Set([ "image", "reference", "resource" ]); const childrenExclude = new Set([ "image", "reference", "resource" ]);
const tokensInclude = new Set([ "codeTextData", "data" ]); const tokensInclude = new Set([ "codeTextData", "data" ]);
/**
* @typedef {import("../helpers/micromark.cjs").Token} Token
*/
/** /**
* Converts a Markdown heading into an HTML fragment according to the rules * Converts a Markdown heading into an HTML fragment according to the rules
* used by GitHub. * used by GitHub.
* *
* @param {Object} headingText Heading text token. * @param {Token} headingText Heading text token.
* @returns {string} Fragment string for heading. * @returns {string} Fragment string for heading.
*/ */
function convertHeadingToHTMLFragment(headingText) { function convertHeadingToHTMLFragment(headingText) {
@ -46,6 +50,18 @@ function convertHeadingToHTMLFragment(headingText) {
); );
} }
/**
* Unescapes the text of a String-type micromark Token.
*
* @param {Token} token String-type micromark Token.
* @returns {string} Unescaped token text.
*/
function unescapeStringTokenText(token) {
return filterByTypes(token.children, [ "characterEscapeValue", "data" ])
.map((child) => child.text)
.join("");
}
module.exports = { module.exports = {
"names": [ "MD051", "link-fragments" ], "names": [ "MD051", "link-fragments" ],
"description": "Link fragments should be valid", "description": "Link fragments should be valid",
@ -99,7 +115,8 @@ module.exports = {
for (const link of links) { for (const link of links) {
const definitions = filterByTypes(link.children, [ definitionType ]); const definitions = filterByTypes(link.children, [ definitionType ]);
for (const definition of definitions) { for (const definition of definitions) {
const { endColumn, startColumn, text } = definition; const { endColumn, startColumn } = definition;
const text = unescapeStringTokenText(definition);
if ( if (
(text.length > 1) && (text.length > 1) &&
text.startsWith("#") && text.startsWith("#") &&

View file

@ -64,6 +64,10 @@
[Valid](#valid-heading-has-) [Valid](#valid-heading-has-)
[Valid](#valid_heading-escaped_underscores)
[Valid](#valid\_heading\-escaped\_underscores)
[Valid](#namedlink) [Valid](#namedlink)
[Valid](#idlink) [Valid](#idlink)
@ -78,6 +82,8 @@
[Valid][goodref] [Valid][goodref]
[Valid][escapedref]
### Valid H3 Heading ### Valid H3 Heading
Text Text
@ -159,6 +165,8 @@ Text
### Valid Heading Has ![an Image](https://example.com) ### Valid Heading Has ![an Image](https://example.com)
### Valid_Heading Escaped_Underscores
<a name="namedlink"></a> <a name="namedlink"></a>
<a id = idlink></a> <a id = idlink></a>
@ -177,6 +185,8 @@ Text
[goodref]: #namedlink [goodref]: #namedlink
[escapedref]: #valid\_heading\-escaped\_underscores
## Invalid Fragments ## Invalid Fragments
[Invalid](#valid-heading-is-an-image) {MD051} [Invalid](#valid-heading-is-an-image) {MD051}

View file

@ -23969,7 +23969,7 @@ Generated by [AVA](https://avajs.dev).
37, 37,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 182, lineNumber: 192,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -23985,7 +23985,7 @@ Generated by [AVA](https://avajs.dev).
31, 31,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 184, lineNumber: 194,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24001,7 +24001,7 @@ Generated by [AVA](https://avajs.dev).
36, 36,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 186, lineNumber: 196,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24017,7 +24017,7 @@ Generated by [AVA](https://avajs.dev).
28, 28,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 188, lineNumber: 198,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24033,7 +24033,7 @@ Generated by [AVA](https://avajs.dev).
18, 18,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 190, lineNumber: 200,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24053,7 +24053,7 @@ Generated by [AVA](https://avajs.dev).
editColumn: 11, editColumn: 11,
insertText: '#HREFandID', insertText: '#HREFandID',
}, },
lineNumber: 192, lineNumber: 202,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24069,7 +24069,7 @@ Generated by [AVA](https://avajs.dev).
34, 34,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 194, lineNumber: 204,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24085,7 +24085,7 @@ Generated by [AVA](https://avajs.dev).
34, 34,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 196, lineNumber: 206,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24101,7 +24101,7 @@ Generated by [AVA](https://avajs.dev).
39, 39,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 198, lineNumber: 208,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24114,7 +24114,7 @@ Generated by [AVA](https://avajs.dev).
errorDetail: null, errorDetail: null,
errorRange: null, errorRange: null,
fixInfo: null, fixInfo: null,
lineNumber: 200, lineNumber: 210,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24130,7 +24130,7 @@ Generated by [AVA](https://avajs.dev).
28, 28,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 205, lineNumber: 215,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24150,7 +24150,7 @@ Generated by [AVA](https://avajs.dev).
editColumn: 9, editColumn: 9,
insertText: '#valid-fragments', insertText: '#valid-fragments',
}, },
lineNumber: 209, lineNumber: 219,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24170,7 +24170,7 @@ Generated by [AVA](https://avajs.dev).
editColumn: 12, editColumn: 12,
insertText: '#namedlink', insertText: '#namedlink',
}, },
lineNumber: 211, lineNumber: 221,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24183,7 +24183,7 @@ Generated by [AVA](https://avajs.dev).
errorDetail: 'Expected: #namedlink; Actual: #NAMEDLINK', errorDetail: 'Expected: #namedlink; Actual: #NAMEDLINK',
errorRange: null, errorRange: null,
fixInfo: null, fixInfo: null,
lineNumber: 213, lineNumber: 223,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24203,7 +24203,7 @@ Generated by [AVA](https://avajs.dev).
editColumn: 13, editColumn: 13,
insertText: '#idlink', insertText: '#idlink',
}, },
lineNumber: 218, lineNumber: 228,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24219,7 +24219,7 @@ Generated by [AVA](https://avajs.dev).
26, 26,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 253, lineNumber: 263,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24235,7 +24235,7 @@ Generated by [AVA](https://avajs.dev).
26, 26,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 255, lineNumber: 265,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24251,7 +24251,7 @@ Generated by [AVA](https://avajs.dev).
20, 20,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 257, lineNumber: 267,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24267,7 +24267,7 @@ Generated by [AVA](https://avajs.dev).
23, 23,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 259, lineNumber: 269,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24283,7 +24283,7 @@ Generated by [AVA](https://avajs.dev).
22, 22,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 261, lineNumber: 271,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24299,7 +24299,7 @@ Generated by [AVA](https://avajs.dev).
42, 42,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 263, lineNumber: 273,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24315,7 +24315,7 @@ Generated by [AVA](https://avajs.dev).
21, 21,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 265, lineNumber: 275,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24331,7 +24331,7 @@ Generated by [AVA](https://avajs.dev).
21, 21,
], ],
fixInfo: null, fixInfo: null,
lineNumber: 267, lineNumber: 277,
ruleDescription: 'Link fragments should be valid', ruleDescription: 'Link fragments should be valid',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md', ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
ruleNames: [ ruleNames: [
@ -24406,6 +24406,10 @@ Generated by [AVA](https://avajs.dev).
[Valid](#valid-heading-has-)␊ [Valid](#valid-heading-has-)␊
[Valid](#valid_heading-escaped_underscores)␊
[Valid](#valid\\_heading\\-escaped\\_underscores)␊
[Valid](#namedlink)␊ [Valid](#namedlink)␊
[Valid](#idlink)␊ [Valid](#idlink)␊
@ -24420,6 +24424,8 @@ Generated by [AVA](https://avajs.dev).
[Valid][goodref]␊ [Valid][goodref]␊
[Valid][escapedref]␊
### Valid H3 Heading␊ ### Valid H3 Heading␊
Text␊ Text␊
@ -24501,6 +24507,8 @@ Generated by [AVA](https://avajs.dev).
### Valid Heading Has ![an Image](https://example.com)␊ ### Valid Heading Has ![an Image](https://example.com)␊
### Valid_Heading Escaped_Underscores␊
<a name="namedlink"></a> <a name="namedlink"></a>
<a id = idlink></a> <a id = idlink></a>
@ -24519,6 +24527,8 @@ Generated by [AVA](https://avajs.dev).
[goodref]: #namedlink [goodref]: #namedlink
[escapedref]: #valid\\_heading\\-escaped\\_underscores␊
## Invalid Fragments␊ ## Invalid Fragments␊
[Invalid](#valid-heading-is-an-image) {MD051}␊ [Invalid](#valid-heading-is-an-image) {MD051}␊