mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Update MD034/no-bare-urls to handle more scenarios, simplify slightly, replace blanket MD034 suppression for https://github.com/mdn/content with specific (valid) issues (refs #607).
This commit is contained in:
parent
2e2937081e
commit
d352d4ece1
6 changed files with 103 additions and 18 deletions
|
|
@ -3756,7 +3756,7 @@ module.exports = {
|
||||||
"use strict";
|
"use strict";
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const { addErrorContext, urlRe, withinAnyRange } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
const { addErrorContext, filterTokens, urlRe, withinAnyRange } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
||||||
const { codeBlockAndSpanRanges, htmlElementRanges, referenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
const { codeBlockAndSpanRanges, htmlElementRanges, referenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
||||||
const htmlLinkRe = /<a(?:|\s[^>]+)>[^<>]*<\/a\s*>/ig;
|
const htmlLinkRe = /<a(?:|\s[^>]+)>[^<>]*<\/a\s*>/ig;
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
@ -3769,6 +3769,11 @@ module.exports = {
|
||||||
...codeBlockAndSpanRanges(),
|
...codeBlockAndSpanRanges(),
|
||||||
...htmlElementRanges()
|
...htmlElementRanges()
|
||||||
];
|
];
|
||||||
|
filterTokens(params, "html_block", (token) => {
|
||||||
|
for (let i = token.map[0]; i < token.map[1]; i++) {
|
||||||
|
codeExclusions.push([i, 0, lines[i].length]);
|
||||||
|
}
|
||||||
|
});
|
||||||
const { definitionLineIndices } = referenceLinkImageData();
|
const { definitionLineIndices } = referenceLinkImageData();
|
||||||
for (const [lineIndex, line] of lines.entries()) {
|
for (const [lineIndex, line] of lines.entries()) {
|
||||||
if (definitionLineIndices[0] === lineIndex) {
|
if (definitionLineIndices[0] === lineIndex) {
|
||||||
|
|
@ -3787,15 +3792,17 @@ module.exports = {
|
||||||
const prefix = line.slice(0, matchIndex);
|
const prefix = line.slice(0, matchIndex);
|
||||||
const postfix = line.slice(matchIndex + bareUrlLength);
|
const postfix = line.slice(matchIndex + bareUrlLength);
|
||||||
if (
|
if (
|
||||||
// Allow ](... to avoid reporting Markdown-style links
|
// Allow <...> to avoid reporting non-bare links
|
||||||
!(/\]\(\s*$/.test(prefix)) &&
|
!(prefix.endsWith("<") && postfix.startsWith(">")) &&
|
||||||
// Allow <...> to avoid reporting non-bare links
|
// Allow >...</ to avoid reporting <code>...</code>
|
||||||
!(prefix.endsWith("<") && /^[#)]?>/.test(postfix)) &&
|
!(prefix.endsWith(">") && postfix.startsWith("</")) &&
|
||||||
// Allow [...] to avoid MD011/no-reversed-links and nested links
|
// Allow "..." and '...' to allow quoting a bare link
|
||||||
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) &&
|
|
||||||
// Allow "..." and '...' for deliberately including a bare link
|
|
||||||
!(prefix.endsWith("\"") && postfix.startsWith("\"")) &&
|
!(prefix.endsWith("\"") && postfix.startsWith("\"")) &&
|
||||||
!(prefix.endsWith("'") && postfix.startsWith("'")) &&
|
!(prefix.endsWith("'") && postfix.startsWith("'")) &&
|
||||||
|
// Allow ](... to avoid reporting Markdown-style links
|
||||||
|
!(/\]\(\s*$/.test(prefix)) &&
|
||||||
|
// Allow [...] to avoid MD011/no-reversed-links and nested links
|
||||||
|
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) &&
|
||||||
!withinAnyRange(lineExclusions, lineIndex, matchIndex, bareUrlLength) &&
|
!withinAnyRange(lineExclusions, lineIndex, matchIndex, bareUrlLength) &&
|
||||||
!withinAnyRange(codeExclusions, lineIndex, matchIndex, bareUrlLength)) {
|
!withinAnyRange(codeExclusions, lineIndex, matchIndex, bareUrlLength)) {
|
||||||
const range = [
|
const range = [
|
||||||
|
|
|
||||||
22
lib/md034.js
22
lib/md034.js
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext, urlRe, withinAnyRange } = require("../helpers");
|
const { addErrorContext, filterTokens, urlRe, withinAnyRange } =
|
||||||
|
require("../helpers");
|
||||||
const { codeBlockAndSpanRanges, htmlElementRanges, referenceLinkImageData } =
|
const { codeBlockAndSpanRanges, htmlElementRanges, referenceLinkImageData } =
|
||||||
require("./cache");
|
require("./cache");
|
||||||
|
|
||||||
|
|
@ -18,6 +19,11 @@ module.exports = {
|
||||||
...codeBlockAndSpanRanges(),
|
...codeBlockAndSpanRanges(),
|
||||||
...htmlElementRanges()
|
...htmlElementRanges()
|
||||||
];
|
];
|
||||||
|
filterTokens(params, "html_block", (token) => {
|
||||||
|
for (let i = token.map[0]; i < token.map[1]; i++) {
|
||||||
|
codeExclusions.push([ i, 0, lines[i].length ]);
|
||||||
|
}
|
||||||
|
});
|
||||||
const { definitionLineIndices } = referenceLinkImageData();
|
const { definitionLineIndices } = referenceLinkImageData();
|
||||||
for (const [ lineIndex, line ] of lines.entries()) {
|
for (const [ lineIndex, line ] of lines.entries()) {
|
||||||
if (definitionLineIndices[0] === lineIndex) {
|
if (definitionLineIndices[0] === lineIndex) {
|
||||||
|
|
@ -35,15 +41,17 @@ module.exports = {
|
||||||
const prefix = line.slice(0, matchIndex);
|
const prefix = line.slice(0, matchIndex);
|
||||||
const postfix = line.slice(matchIndex + bareUrlLength);
|
const postfix = line.slice(matchIndex + bareUrlLength);
|
||||||
if (
|
if (
|
||||||
// Allow ](... to avoid reporting Markdown-style links
|
|
||||||
!(/\]\(\s*$/.test(prefix)) &&
|
|
||||||
// Allow <...> to avoid reporting non-bare links
|
// Allow <...> to avoid reporting non-bare links
|
||||||
!(prefix.endsWith("<") && /^[#)]?>/.test(postfix)) &&
|
!(prefix.endsWith("<") && postfix.startsWith(">")) &&
|
||||||
// Allow [...] to avoid MD011/no-reversed-links and nested links
|
// Allow >...</ to avoid reporting <code>...</code>
|
||||||
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) &&
|
!(prefix.endsWith(">") && postfix.startsWith("</")) &&
|
||||||
// Allow "..." and '...' for deliberately including a bare link
|
// Allow "..." and '...' to allow quoting a bare link
|
||||||
!(prefix.endsWith("\"") && postfix.startsWith("\"")) &&
|
!(prefix.endsWith("\"") && postfix.startsWith("\"")) &&
|
||||||
!(prefix.endsWith("'") && postfix.startsWith("'")) &&
|
!(prefix.endsWith("'") && postfix.startsWith("'")) &&
|
||||||
|
// Allow ](... to avoid reporting Markdown-style links
|
||||||
|
!(/\]\(\s*$/.test(prefix)) &&
|
||||||
|
// Allow [...] to avoid MD011/no-reversed-links and nested links
|
||||||
|
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) &&
|
||||||
!withinAnyRange(
|
!withinAnyRange(
|
||||||
lineExclusions, lineIndex, matchIndex, bareUrlLength
|
lineExclusions, lineIndex, matchIndex, bareUrlLength
|
||||||
) &&
|
) &&
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,11 @@ As is <a href="https://example.com/info.htm">https://example.com/info.htm text</
|
||||||
|
|
||||||
This is not a bare [link]( https://example.com ).
|
This is not a bare [link]( https://example.com ).
|
||||||
|
|
||||||
URLs in HTML are not bare:
|
Nor is [link](https://example.com/path-with(parens)).
|
||||||
|
|
||||||
|
Or <https://example.com/path-with(parens)>.
|
||||||
|
|
||||||
|
URLs in HTML attributes are not bare:
|
||||||
|
|
||||||
<element-name first-attribute=" https://example.com/first " second-attribute=" https://example.com/second ">
|
<element-name first-attribute=" https://example.com/first " second-attribute=" https://example.com/second ">
|
||||||
Text
|
Text
|
||||||
|
|
@ -42,8 +46,27 @@ URLs in HTML are not bare:
|
||||||
first-attribute=" https://example.com/first "
|
first-attribute=" https://example.com/first "
|
||||||
second-attribute=" https://example.com/second "></element-name>
|
second-attribute=" https://example.com/second "></element-name>
|
||||||
|
|
||||||
|
URLs surrounded by HTML tags are not bare:
|
||||||
|
|
||||||
|
Not <code>https://example.com</code> bare.
|
||||||
|
|
||||||
|
Not <pre>https://example.com</pre> bare.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Not bare due to being in an HTML block:
|
||||||
|
https://example.com
|
||||||
|
<code>https://example.com</code>
|
||||||
|
<pre>https://example.com</pre>
|
||||||
|
</p>
|
||||||
|
|
||||||
URLs in link and image text are not bare:
|
URLs in link and image text are not bare:
|
||||||
|
|
||||||
Text [link to https://example.com site](https://example.com) text.
|
Text [link to https://example.com site](https://example.com) text.
|
||||||
|
|
||||||
Image  text.
|
Image  text.
|
||||||
|
|
||||||
|
URLs may end with a dash: https://example.com#heading- {MD034}
|
||||||
|
|
||||||
|
... when explicit: <https://example.com#heading->
|
||||||
|
|
||||||
|
... when embedded: <code>https://example.com#heading-</code>
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,11 @@ test("https://github.com/mdn/content", (t) => {
|
||||||
const rootDir = "./test-repos/mdn-content";
|
const rootDir = "./test-repos/mdn-content";
|
||||||
const globPatterns = [ join(rootDir, "**/*.md") ];
|
const globPatterns = [ join(rootDir, "**/*.md") ];
|
||||||
const configPath = join(rootDir, ".markdownlint-cli2.jsonc");
|
const configPath = join(rootDir, ".markdownlint-cli2.jsonc");
|
||||||
const ignoreRes = [ /^[^:]+: \d+: MD034\/.*$\r?\n?/gm ];
|
const ignoreRes = [
|
||||||
|
/test-repos\/mdn-content\/files\/en-us\/mdn\/community\/pull_requests\/index.md: \d+: MD034\/.*$\r?\n?/gm,
|
||||||
|
/test-repos\/mdn-content\/files\/en-us\/web\/api\/customelementregistry\/whendefined\/index.md: \d+: MD034\/.*$\r?\n?/gm,
|
||||||
|
/test-repos\/mdn-content\/files\/en-us\/web\/api\/css_painting_api\/guide\/index.md: \d+: MD034\/.*$\r?\n?/gm
|
||||||
|
];
|
||||||
return lintTestRepo(t, globPatterns, configPath, ignoreRes);
|
return lintTestRepo(t, globPatterns, configPath, ignoreRes);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2966,6 +2966,26 @@ Generated by [AVA](https://avajs.dev).
|
||||||
'no-bare-urls',
|
'no-bare-urls',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
errorContext: 'https://example.com#heading-',
|
||||||
|
errorDetail: null,
|
||||||
|
errorRange: [
|
||||||
|
27,
|
||||||
|
28,
|
||||||
|
],
|
||||||
|
fixInfo: {
|
||||||
|
deleteCount: 28,
|
||||||
|
editColumn: 27,
|
||||||
|
insertText: '<https://example.com#heading->',
|
||||||
|
},
|
||||||
|
lineNumber: 68,
|
||||||
|
ruleDescription: 'Bare URL used',
|
||||||
|
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md034.md',
|
||||||
|
ruleNames: [
|
||||||
|
'MD034',
|
||||||
|
'no-bare-urls',
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
fixed: `# Detailed Results Bare URLs␊
|
fixed: `# Detailed Results Bare URLs␊
|
||||||
␊
|
␊
|
||||||
|
|
@ -3001,7 +3021,11 @@ Generated by [AVA](https://avajs.dev).
|
||||||
␊
|
␊
|
||||||
This is not a bare [link]( https://example.com ).␊
|
This is not a bare [link]( https://example.com ).␊
|
||||||
␊
|
␊
|
||||||
URLs in HTML are not bare:␊
|
Nor is [link](https://example.com/path-with(parens)).␊
|
||||||
|
␊
|
||||||
|
Or <https://example.com/path-with(parens)>.␊
|
||||||
|
␊
|
||||||
|
URLs in HTML attributes are not bare:␊
|
||||||
␊
|
␊
|
||||||
<element-name first-attribute=" https://example.com/first " second-attribute=" https://example.com/second ">␊
|
<element-name first-attribute=" https://example.com/first " second-attribute=" https://example.com/second ">␊
|
||||||
Text␊
|
Text␊
|
||||||
|
|
@ -3011,11 +3035,30 @@ Generated by [AVA](https://avajs.dev).
|
||||||
first-attribute=" https://example.com/first "␊
|
first-attribute=" https://example.com/first "␊
|
||||||
second-attribute=" https://example.com/second "></element-name>␊
|
second-attribute=" https://example.com/second "></element-name>␊
|
||||||
␊
|
␊
|
||||||
|
URLs surrounded by HTML tags are not bare:␊
|
||||||
|
␊
|
||||||
|
Not <code>https://example.com</code> bare.␊
|
||||||
|
␊
|
||||||
|
Not <pre>https://example.com</pre> bare.␊
|
||||||
|
␊
|
||||||
|
<p>␊
|
||||||
|
Not bare due to being in an HTML block:␊
|
||||||
|
https://example.com␊
|
||||||
|
<code>https://example.com</code>␊
|
||||||
|
<pre>https://example.com</pre>␊
|
||||||
|
</p>␊
|
||||||
|
␊
|
||||||
URLs in link and image text are not bare:␊
|
URLs in link and image text are not bare:␊
|
||||||
␊
|
␊
|
||||||
Text [link to https://example.com site](https://example.com) text.␊
|
Text [link to https://example.com site](https://example.com) text.␊
|
||||||
␊
|
␊
|
||||||
Image  text.␊
|
Image  text.␊
|
||||||
|
␊
|
||||||
|
URLs may end with a dash: <https://example.com#heading-> {MD034}␊
|
||||||
|
␊
|
||||||
|
... when explicit: <https://example.com#heading->␊
|
||||||
|
␊
|
||||||
|
... when embedded: <code>https://example.com#heading-</code>␊
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue