diff --git a/src/rules/no-bare-urls.js b/src/rules/no-bare-urls.js index 30f0d834..7a018956 100644 --- a/src/rules/no-bare-urls.js +++ b/src/rules/no-bare-urls.js @@ -168,7 +168,25 @@ export default /** @satisfies {NoBareUrlsRuleDefinition} */ ({ node: linkNode, messageId: "bareUrl", fix(fixer) { - return fixer.replaceText(linkNode, `<${text}>`); + let replacementText = `<${text}>`; + // GFM parses `www` autolinks with an `http://` URL. + if (url === `http://${text}`) { + const escapedLinkText = text.replace( + /[[\]\\*_~`]/gu, + "\\$&", + ); + const escapedLinkDestination = url.replace( + /[\\()]/gu, + "\\$&", + ); + + replacementText = `[${escapedLinkText}](${escapedLinkDestination})`; + } + + return fixer.replaceText( + linkNode, + replacementText, + ); }, }); } diff --git a/tests/rules/no-bare-urls.test.js b/tests/rules/no-bare-urls.test.js index df9d171b..ba3db031 100644 --- a/tests/rules/no-bare-urls.test.js +++ b/tests/rules/no-bare-urls.test.js @@ -73,6 +73,110 @@ ruleTester.run("no-bare-urls", rule, { " Code https://example.com/code?type=indent code", ], invalid: [ + { + code: "Visit www.example.com for details.", + output: "Visit [www.example.com](http://www.example.com) for details.", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 7, + endLine: 1, + endColumn: 22, + }, + ], + }, + { + code: "www.google.com/search?q=(business))+ok", + output: "[www.google.com/search?q=(business))+ok](http://www.google.com/search?q=\\(business\\)\\)+ok)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 39, + }, + ], + }, + { + code: "www.example.com/a\\*b", + output: "[www.example.com/a\\\\\\*b](http://www.example.com/a\\\\*b)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 21, + }, + ], + }, + { + code: "www.example.com/a]b", + output: "[www.example.com/a\\]b](http://www.example.com/a]b)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 20, + }, + ], + }, + { + code: "www.example.com/a[b", + output: "[www.example.com/a\\[b](http://www.example.com/a[b)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 20, + }, + ], + }, + { + code: "www.example.com/a*b*c", + output: "[www.example.com/a\\*b\\*c](http://www.example.com/a*b*c)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 22, + }, + ], + }, + { + code: "www.example.com/a~b~c", + output: "[www.example.com/a\\~b\\~c](http://www.example.com/a~b~c)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 22, + }, + ], + }, + { + code: "www.example.com/a`b`c", + output: "[www.example.com/a\\`b\\`c](http://www.example.com/a`b`c)", + errors: [ + { + messageId: "bareUrl", + line: 1, + column: 1, + endLine: 1, + endColumn: 22, + }, + ], + }, { code: "https://www.example.com/", output: "",