mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Refactor to remove helper withinAnyRange.
This commit is contained in:
parent
5e568d0da9
commit
124b7e2276
3 changed files with 60 additions and 92 deletions
|
|
@ -386,24 +386,6 @@ function addErrorContextForLine(onError, lines, lineIndex, lineNumber) {
|
||||||
}
|
}
|
||||||
module.exports.addErrorContextForLine = addErrorContextForLine;
|
module.exports.addErrorContextForLine = addErrorContextForLine;
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the specified range is within another range.
|
|
||||||
*
|
|
||||||
* @param {number[][]} ranges Array of ranges (line, index, length).
|
|
||||||
* @param {number} lineIndex Line index to check.
|
|
||||||
* @param {number} index Index to check.
|
|
||||||
* @param {number} length Length to check.
|
|
||||||
* @returns {boolean} True iff the specified range is within.
|
|
||||||
*/
|
|
||||||
const withinAnyRange = (ranges, lineIndex, index, length) => (
|
|
||||||
!ranges.every((span) => (
|
|
||||||
(lineIndex !== span[0]) ||
|
|
||||||
(index < span[1]) ||
|
|
||||||
(index + length > span[1] + span[2])
|
|
||||||
))
|
|
||||||
);
|
|
||||||
module.exports.withinAnyRange = withinAnyRange;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a range within a file (start line/column to end line/column, subset of MicromarkToken).
|
* Defines a range within a file (start line/column to end line/column, subset of MicromarkToken).
|
||||||
*
|
*
|
||||||
|
|
@ -5819,10 +5801,8 @@ module.exports = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { addErrorDetailIf, escapeForRegExp, withinAnyRange } =
|
const { addErrorDetailIf, escapeForRegExp, hasOverlap } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
||||||
__webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
const { filterByPredicate, filterByTypes, parse } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
||||||
const { filterByPredicate, filterByTypes, parse } =
|
|
||||||
__webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
||||||
|
|
||||||
const ignoredChildTypes = new Set(
|
const ignoredChildTypes = new Set(
|
||||||
[ "codeFencedFence", "definition", "reference", "resource" ]
|
[ "codeFencedFence", "definition", "reference", "resource" ]
|
||||||
|
|
@ -5866,43 +5846,47 @@ module.exports = {
|
||||||
token.children.filter((t) => !ignoredChildTypes.has(t.type))
|
token.children.filter((t) => !ignoredChildTypes.has(t.type))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
/** @type {import("../helpers").FileRange[]} */
|
||||||
const exclusions = [];
|
const exclusions = [];
|
||||||
const autoLinked = new Set();
|
const scannedTokens = new Set();
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
const escapedName = escapeForRegExp(name);
|
const escapedName = escapeForRegExp(name);
|
||||||
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
||||||
const endNamePattern = /\W$/.test(name) ? "" : "_*\\b";
|
const endNamePattern = /\W$/.test(name) ? "" : "_*\\b";
|
||||||
const namePattern =
|
const namePattern = `(${startNamePattern})(${escapedName})${endNamePattern}`;
|
||||||
`(${startNamePattern})(${escapedName})${endNamePattern}`;
|
|
||||||
const nameRe = new RegExp(namePattern, "gi");
|
const nameRe = new RegExp(namePattern, "gi");
|
||||||
for (const token of contentTokens) {
|
for (const token of contentTokens) {
|
||||||
let match = null;
|
let match = null;
|
||||||
while ((match = nameRe.exec(token.text)) !== null) {
|
while ((match = nameRe.exec(token.text)) !== null) {
|
||||||
const [ , leftMatch, nameMatch ] = match;
|
const [ , leftMatch, nameMatch ] = match;
|
||||||
const index = token.startColumn - 1 + match.index + leftMatch.length;
|
const column = token.startColumn + match.index + leftMatch.length;
|
||||||
const length = nameMatch.length;
|
const length = nameMatch.length;
|
||||||
const lineIndex = token.startLine - 1;
|
const lineNumber = token.startLine;
|
||||||
|
/** @type {import("../helpers").FileRange} */
|
||||||
|
const nameRange = {
|
||||||
|
"startLine": lineNumber,
|
||||||
|
"startColumn": column,
|
||||||
|
"endLine": lineNumber,
|
||||||
|
"endColumn": column + length - 1
|
||||||
|
};
|
||||||
if (
|
if (
|
||||||
!withinAnyRange(exclusions, lineIndex, index, length) &&
|
!names.includes(nameMatch) &&
|
||||||
!names.includes(nameMatch)
|
!exclusions.some((exclusion) => hasOverlap(exclusion, nameRange))
|
||||||
) {
|
) {
|
||||||
let urlRanges = [];
|
/** @type {import("../helpers").FileRange[]} */
|
||||||
if (!autoLinked.has(token)) {
|
let autolinkRanges = [];
|
||||||
urlRanges = filterByTypes(
|
if (!scannedTokens.has(token)) {
|
||||||
parse(token.text),
|
autolinkRanges = filterByTypes(parse(token.text), [ "literalAutolink" ])
|
||||||
[ "literalAutolink" ]
|
.map((tok) => ({
|
||||||
).map(
|
"startLine": lineNumber,
|
||||||
(t) => [
|
"startColumn": token.startColumn + tok.startColumn - 1,
|
||||||
lineIndex,
|
"endLine": lineNumber,
|
||||||
token.startColumn - 1 + t.startColumn - 1,
|
"endColumn": token.endColumn + tok.endColumn - 1
|
||||||
t.endColumn - t.startColumn
|
}));
|
||||||
]
|
exclusions.push(...autolinkRanges);
|
||||||
);
|
scannedTokens.add(token);
|
||||||
exclusions.push(...urlRanges);
|
|
||||||
autoLinked.add(token);
|
|
||||||
}
|
}
|
||||||
if (!withinAnyRange(urlRanges, lineIndex, index, length)) {
|
if (!autolinkRanges.some((autolinkRange) => hasOverlap(autolinkRange, nameRange))) {
|
||||||
const column = index + 1;
|
|
||||||
addErrorDetailIf(
|
addErrorDetailIf(
|
||||||
onError,
|
onError,
|
||||||
token.startLine,
|
token.startLine,
|
||||||
|
|
@ -5919,7 +5903,7 @@ module.exports = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exclusions.push([ lineIndex, index, length ]);
|
exclusions.push(nameRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -374,24 +374,6 @@ function addErrorContextForLine(onError, lines, lineIndex, lineNumber) {
|
||||||
}
|
}
|
||||||
module.exports.addErrorContextForLine = addErrorContextForLine;
|
module.exports.addErrorContextForLine = addErrorContextForLine;
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the specified range is within another range.
|
|
||||||
*
|
|
||||||
* @param {number[][]} ranges Array of ranges (line, index, length).
|
|
||||||
* @param {number} lineIndex Line index to check.
|
|
||||||
* @param {number} index Index to check.
|
|
||||||
* @param {number} length Length to check.
|
|
||||||
* @returns {boolean} True iff the specified range is within.
|
|
||||||
*/
|
|
||||||
const withinAnyRange = (ranges, lineIndex, index, length) => (
|
|
||||||
!ranges.every((span) => (
|
|
||||||
(lineIndex !== span[0]) ||
|
|
||||||
(index < span[1]) ||
|
|
||||||
(index + length > span[1] + span[2])
|
|
||||||
))
|
|
||||||
);
|
|
||||||
module.exports.withinAnyRange = withinAnyRange;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a range within a file (start line/column to end line/column, subset of MicromarkToken).
|
* Defines a range within a file (start line/column to end line/column, subset of MicromarkToken).
|
||||||
*
|
*
|
||||||
|
|
|
||||||
58
lib/md044.js
58
lib/md044.js
|
|
@ -2,10 +2,8 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf, escapeForRegExp, withinAnyRange } =
|
const { addErrorDetailIf, escapeForRegExp, hasOverlap } = require("../helpers");
|
||||||
require("../helpers");
|
const { filterByPredicate, filterByTypes, parse } = require("../helpers/micromark.cjs");
|
||||||
const { filterByPredicate, filterByTypes, parse } =
|
|
||||||
require("../helpers/micromark.cjs");
|
|
||||||
|
|
||||||
const ignoredChildTypes = new Set(
|
const ignoredChildTypes = new Set(
|
||||||
[ "codeFencedFence", "definition", "reference", "resource" ]
|
[ "codeFencedFence", "definition", "reference", "resource" ]
|
||||||
|
|
@ -49,43 +47,47 @@ module.exports = {
|
||||||
token.children.filter((t) => !ignoredChildTypes.has(t.type))
|
token.children.filter((t) => !ignoredChildTypes.has(t.type))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
/** @type {import("../helpers").FileRange[]} */
|
||||||
const exclusions = [];
|
const exclusions = [];
|
||||||
const autoLinked = new Set();
|
const scannedTokens = new Set();
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
const escapedName = escapeForRegExp(name);
|
const escapedName = escapeForRegExp(name);
|
||||||
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
||||||
const endNamePattern = /\W$/.test(name) ? "" : "_*\\b";
|
const endNamePattern = /\W$/.test(name) ? "" : "_*\\b";
|
||||||
const namePattern =
|
const namePattern = `(${startNamePattern})(${escapedName})${endNamePattern}`;
|
||||||
`(${startNamePattern})(${escapedName})${endNamePattern}`;
|
|
||||||
const nameRe = new RegExp(namePattern, "gi");
|
const nameRe = new RegExp(namePattern, "gi");
|
||||||
for (const token of contentTokens) {
|
for (const token of contentTokens) {
|
||||||
let match = null;
|
let match = null;
|
||||||
while ((match = nameRe.exec(token.text)) !== null) {
|
while ((match = nameRe.exec(token.text)) !== null) {
|
||||||
const [ , leftMatch, nameMatch ] = match;
|
const [ , leftMatch, nameMatch ] = match;
|
||||||
const index = token.startColumn - 1 + match.index + leftMatch.length;
|
const column = token.startColumn + match.index + leftMatch.length;
|
||||||
const length = nameMatch.length;
|
const length = nameMatch.length;
|
||||||
const lineIndex = token.startLine - 1;
|
const lineNumber = token.startLine;
|
||||||
|
/** @type {import("../helpers").FileRange} */
|
||||||
|
const nameRange = {
|
||||||
|
"startLine": lineNumber,
|
||||||
|
"startColumn": column,
|
||||||
|
"endLine": lineNumber,
|
||||||
|
"endColumn": column + length - 1
|
||||||
|
};
|
||||||
if (
|
if (
|
||||||
!withinAnyRange(exclusions, lineIndex, index, length) &&
|
!names.includes(nameMatch) &&
|
||||||
!names.includes(nameMatch)
|
!exclusions.some((exclusion) => hasOverlap(exclusion, nameRange))
|
||||||
) {
|
) {
|
||||||
let urlRanges = [];
|
/** @type {import("../helpers").FileRange[]} */
|
||||||
if (!autoLinked.has(token)) {
|
let autolinkRanges = [];
|
||||||
urlRanges = filterByTypes(
|
if (!scannedTokens.has(token)) {
|
||||||
parse(token.text),
|
autolinkRanges = filterByTypes(parse(token.text), [ "literalAutolink" ])
|
||||||
[ "literalAutolink" ]
|
.map((tok) => ({
|
||||||
).map(
|
"startLine": lineNumber,
|
||||||
(t) => [
|
"startColumn": token.startColumn + tok.startColumn - 1,
|
||||||
lineIndex,
|
"endLine": lineNumber,
|
||||||
token.startColumn - 1 + t.startColumn - 1,
|
"endColumn": token.endColumn + tok.endColumn - 1
|
||||||
t.endColumn - t.startColumn
|
}));
|
||||||
]
|
exclusions.push(...autolinkRanges);
|
||||||
);
|
scannedTokens.add(token);
|
||||||
exclusions.push(...urlRanges);
|
|
||||||
autoLinked.add(token);
|
|
||||||
}
|
}
|
||||||
if (!withinAnyRange(urlRanges, lineIndex, index, length)) {
|
if (!autolinkRanges.some((autolinkRange) => hasOverlap(autolinkRange, nameRange))) {
|
||||||
const column = index + 1;
|
|
||||||
addErrorDetailIf(
|
addErrorDetailIf(
|
||||||
onError,
|
onError,
|
||||||
token.startLine,
|
token.startLine,
|
||||||
|
|
@ -102,7 +104,7 @@ module.exports = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exclusions.push([ lineIndex, index, length ]);
|
exclusions.push(nameRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue