mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Reimplement MD051/link-fragments using micromark tokens, report reference link issues for definition and fix when possible, handle reporting multiple violations on the same line better.
This commit is contained in:
parent
dd73b0ad7f
commit
ef1bd286a9
14 changed files with 458 additions and 346 deletions
|
|
@ -223,6 +223,7 @@
|
||||||
"unicorn/no-new-array": "off",
|
"unicorn/no-new-array": "off",
|
||||||
"unicorn/no-null": "off",
|
"unicorn/no-null": "off",
|
||||||
"unicorn/no-unsafe-regex": "off",
|
"unicorn/no-unsafe-regex": "off",
|
||||||
|
"unicorn/no-useless-undefined": "off",
|
||||||
"unicorn/prefer-at": "off",
|
"unicorn/prefer-at": "off",
|
||||||
"unicorn/prefer-module": "off",
|
"unicorn/prefer-module": "off",
|
||||||
"unicorn/prefer-string-replace-all": "off",
|
"unicorn/prefer-string-replace-all": "off",
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,6 @@ var inlineCommentStartRe =
|
||||||
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi;
|
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi;
|
||||||
module.exports.inlineCommentStartRe = inlineCommentStartRe;
|
module.exports.inlineCommentStartRe = inlineCommentStartRe;
|
||||||
|
|
||||||
// Regular expression for matching HTML elements
|
|
||||||
var htmlElementRe = /<(([A-Za-z][A-Za-z\d-]*)(?:\s[^`>]*)?)\/?>/g;
|
|
||||||
module.exports.htmlElementRe = htmlElementRe;
|
|
||||||
|
|
||||||
// Regular expressions for range matching
|
// Regular expressions for range matching
|
||||||
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/;
|
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/;
|
||||||
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/;
|
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/;
|
||||||
|
|
@ -495,42 +491,14 @@ module.exports.flattenLists = function flattenLists(tokens) {
|
||||||
return flattenedLists;
|
return flattenedLists;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the provided function for each specified inline child token.
|
|
||||||
*
|
|
||||||
* @param {Object} params RuleParams instance.
|
|
||||||
* @param {string} type Token type identifier.
|
|
||||||
* @param {Function} handler Callback function.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
function forEachInlineChild(params, type, handler) {
|
|
||||||
filterTokens(params, "inline", function (token) {
|
|
||||||
var _iterator4 = _createForOfIteratorHelper(token.children.filter(function (c) {
|
|
||||||
return c.type === type;
|
|
||||||
})),
|
|
||||||
_step4;
|
|
||||||
try {
|
|
||||||
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
||||||
var child = _step4.value;
|
|
||||||
handler(child, token);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
_iterator4.e(err);
|
|
||||||
} finally {
|
|
||||||
_iterator4.f();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
module.exports.forEachInlineChild = forEachInlineChild;
|
|
||||||
|
|
||||||
// Calls the provided function for each heading's content
|
// Calls the provided function for each heading's content
|
||||||
module.exports.forEachHeading = function forEachHeading(params, handler) {
|
module.exports.forEachHeading = function forEachHeading(params, handler) {
|
||||||
var heading = null;
|
var heading = null;
|
||||||
var _iterator5 = _createForOfIteratorHelper(params.parsers.markdownit.tokens),
|
var _iterator4 = _createForOfIteratorHelper(params.parsers.markdownit.tokens),
|
||||||
_step5;
|
_step4;
|
||||||
try {
|
try {
|
||||||
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
||||||
var token = _step5.value;
|
var token = _step4.value;
|
||||||
if (token.type === "heading_open") {
|
if (token.type === "heading_open") {
|
||||||
heading = token;
|
heading = token;
|
||||||
} else if (token.type === "heading_close") {
|
} else if (token.type === "heading_close") {
|
||||||
|
|
@ -540,9 +508,9 @@ module.exports.forEachHeading = function forEachHeading(params, handler) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_iterator5.e(err);
|
_iterator4.e(err);
|
||||||
} finally {
|
} finally {
|
||||||
_iterator5.f();
|
_iterator4.f();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -677,19 +645,19 @@ module.exports.codeBlockAndSpanRanges = function (params, lineMetadata) {
|
||||||
var tokenLines = params.lines.slice(token.map[0], token.map[1]);
|
var tokenLines = params.lines.slice(token.map[0], token.map[1]);
|
||||||
forEachInlineCodeSpan(tokenLines.join("\n"), function (code, lineIndex, columnIndex) {
|
forEachInlineCodeSpan(tokenLines.join("\n"), function (code, lineIndex, columnIndex) {
|
||||||
var codeLines = code.split(newLineRe);
|
var codeLines = code.split(newLineRe);
|
||||||
var _iterator6 = _createForOfIteratorHelper(codeLines.entries()),
|
var _iterator5 = _createForOfIteratorHelper(codeLines.entries()),
|
||||||
_step6;
|
_step5;
|
||||||
try {
|
try {
|
||||||
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
||||||
var _step6$value = _slicedToArray(_step6.value, 2),
|
var _step5$value = _slicedToArray(_step5.value, 2),
|
||||||
i = _step6$value[0],
|
i = _step5$value[0],
|
||||||
line = _step6$value[1];
|
line = _step5$value[1];
|
||||||
exclusions.push([token.lineNumber - 1 + lineIndex + i, i ? 0 : columnIndex, line.length]);
|
exclusions.push([token.lineNumber - 1 + lineIndex + i, i ? 0 : columnIndex, line.length]);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_iterator6.e(err);
|
_iterator5.e(err);
|
||||||
} finally {
|
} finally {
|
||||||
_iterator6.f();
|
_iterator5.f();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -756,11 +724,11 @@ function getReferenceLinkImageData(params) {
|
||||||
"definitionLabelString", "gfmFootnoteDefinitionLabelString",
|
"definitionLabelString", "gfmFootnoteDefinitionLabelString",
|
||||||
// references and shortcuts
|
// references and shortcuts
|
||||||
"gfmFootnoteCall", "image", "link"]);
|
"gfmFootnoteCall", "image", "link"]);
|
||||||
var _iterator7 = _createForOfIteratorHelper(filteredTokens),
|
var _iterator6 = _createForOfIteratorHelper(filteredTokens),
|
||||||
_step7;
|
_step6;
|
||||||
try {
|
try {
|
||||||
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
||||||
var token = _step7.value;
|
var token = _step6.value;
|
||||||
var labelPrefix = "";
|
var labelPrefix = "";
|
||||||
// eslint-disable-next-line default-case
|
// eslint-disable-next-line default-case
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
|
|
@ -827,9 +795,9 @@ function getReferenceLinkImageData(params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_iterator7.e(err);
|
_iterator6.e(err);
|
||||||
} finally {
|
} finally {
|
||||||
_iterator7.f();
|
_iterator6.f();
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
references: references,
|
references: references,
|
||||||
|
|
@ -853,11 +821,11 @@ function getPreferredLineEnding(input, os) {
|
||||||
var lf = 0;
|
var lf = 0;
|
||||||
var crlf = 0;
|
var crlf = 0;
|
||||||
var endings = input.match(newLineRe) || [];
|
var endings = input.match(newLineRe) || [];
|
||||||
var _iterator8 = _createForOfIteratorHelper(endings),
|
var _iterator7 = _createForOfIteratorHelper(endings),
|
||||||
_step8;
|
_step7;
|
||||||
try {
|
try {
|
||||||
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
||||||
var ending = _step8.value;
|
var ending = _step7.value;
|
||||||
// eslint-disable-next-line default-case
|
// eslint-disable-next-line default-case
|
||||||
switch (ending) {
|
switch (ending) {
|
||||||
case "\r":
|
case "\r":
|
||||||
|
|
@ -872,9 +840,9 @@ function getPreferredLineEnding(input, os) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_iterator8.e(err);
|
_iterator7.e(err);
|
||||||
} finally {
|
} finally {
|
||||||
_iterator8.f();
|
_iterator7.f();
|
||||||
}
|
}
|
||||||
var preferredLineEnding = null;
|
var preferredLineEnding = null;
|
||||||
if (!cr && !lf && !crlf) {
|
if (!cr && !lf && !crlf) {
|
||||||
|
|
@ -957,11 +925,11 @@ function applyFixes(input, errors) {
|
||||||
lastFixInfo = {
|
lastFixInfo = {
|
||||||
"lineNumber": -1
|
"lineNumber": -1
|
||||||
};
|
};
|
||||||
var _iterator9 = _createForOfIteratorHelper(fixInfos),
|
var _iterator8 = _createForOfIteratorHelper(fixInfos),
|
||||||
_step9;
|
_step8;
|
||||||
try {
|
try {
|
||||||
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
||||||
var fixInfo = _step9.value;
|
var fixInfo = _step8.value;
|
||||||
if (fixInfo.lineNumber === lastFixInfo.lineNumber && fixInfo.editColumn === lastFixInfo.editColumn && !fixInfo.insertText && fixInfo.deleteCount > 0 && lastFixInfo.insertText && !lastFixInfo.deleteCount) {
|
if (fixInfo.lineNumber === lastFixInfo.lineNumber && fixInfo.editColumn === lastFixInfo.editColumn && !fixInfo.insertText && fixInfo.deleteCount > 0 && lastFixInfo.insertText && !lastFixInfo.deleteCount) {
|
||||||
fixInfo.insertText = lastFixInfo.insertText;
|
fixInfo.insertText = lastFixInfo.insertText;
|
||||||
lastFixInfo.lineNumber = 0;
|
lastFixInfo.lineNumber = 0;
|
||||||
|
|
@ -969,9 +937,9 @@ function applyFixes(input, errors) {
|
||||||
lastFixInfo = fixInfo;
|
lastFixInfo = fixInfo;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_iterator9.e(err);
|
_iterator8.e(err);
|
||||||
} finally {
|
} finally {
|
||||||
_iterator9.f();
|
_iterator8.f();
|
||||||
}
|
}
|
||||||
fixInfos = fixInfos.filter(function (fixInfo) {
|
fixInfos = fixInfos.filter(function (fixInfo) {
|
||||||
return fixInfo.lineNumber;
|
return fixInfo.lineNumber;
|
||||||
|
|
@ -979,11 +947,11 @@ function applyFixes(input, errors) {
|
||||||
// Apply all (remaining/updated) fixes
|
// Apply all (remaining/updated) fixes
|
||||||
var lastLineIndex = -1;
|
var lastLineIndex = -1;
|
||||||
var lastEditIndex = -1;
|
var lastEditIndex = -1;
|
||||||
var _iterator10 = _createForOfIteratorHelper(fixInfos),
|
var _iterator9 = _createForOfIteratorHelper(fixInfos),
|
||||||
_step10;
|
_step9;
|
||||||
try {
|
try {
|
||||||
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
||||||
var _fixInfo = _step10.value;
|
var _fixInfo = _step9.value;
|
||||||
var lineNumber = _fixInfo.lineNumber,
|
var lineNumber = _fixInfo.lineNumber,
|
||||||
editColumn = _fixInfo.editColumn,
|
editColumn = _fixInfo.editColumn,
|
||||||
deleteCount = _fixInfo.deleteCount;
|
deleteCount = _fixInfo.deleteCount;
|
||||||
|
|
@ -998,9 +966,9 @@ function applyFixes(input, errors) {
|
||||||
}
|
}
|
||||||
// Return corrected input
|
// Return corrected input
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_iterator10.e(err);
|
_iterator9.e(err);
|
||||||
} finally {
|
} finally {
|
||||||
_iterator10.f();
|
_iterator9.f();
|
||||||
}
|
}
|
||||||
return lines.filter(function (line) {
|
return lines.filter(function (line) {
|
||||||
return line !== null;
|
return line !== null;
|
||||||
|
|
@ -1348,6 +1316,39 @@ function filterByTypes(tokens, allowed) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a list of Micromark tokens for HTML tokens.
|
||||||
|
*
|
||||||
|
* @param {Token[]} tokens Micromark tokens.
|
||||||
|
* @returns {Token[]} Filtered tokens.
|
||||||
|
*/
|
||||||
|
function filterByHtmlTokens(tokens) {
|
||||||
|
var result = [];
|
||||||
|
var pending = [tokens];
|
||||||
|
var current = null;
|
||||||
|
while (current = pending.shift()) {
|
||||||
|
var _iterator2 = _createForOfIteratorHelper(filterByTypes(current, ["htmlFlow", "htmlText"])),
|
||||||
|
_step2;
|
||||||
|
try {
|
||||||
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
||||||
|
var token = _step2.value;
|
||||||
|
if (token.type === "htmlText") {
|
||||||
|
result.push(token);
|
||||||
|
} else {
|
||||||
|
// token.type === "htmlFlow"
|
||||||
|
// @ts-ignore
|
||||||
|
pending.push(token.htmlFlowChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator2.e(err);
|
||||||
|
} finally {
|
||||||
|
_iterator2.f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all nested child tokens.
|
* Returns a list of all nested child tokens.
|
||||||
*
|
*
|
||||||
|
|
@ -1438,6 +1439,7 @@ function tokenIfType(token, type) {
|
||||||
}
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"parse": micromarkParse,
|
"parse": micromarkParse,
|
||||||
|
filterByHtmlTokens: filterByHtmlTokens,
|
||||||
filterByPredicate: filterByPredicate,
|
filterByPredicate: filterByPredicate,
|
||||||
filterByTypes: filterByTypes,
|
filterByTypes: filterByTypes,
|
||||||
flattenedChildren: flattenedChildren,
|
flattenedChildren: flattenedChildren,
|
||||||
|
|
@ -4855,7 +4857,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
||||||
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
|
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
|
||||||
addError = _require.addError;
|
addError = _require.addError;
|
||||||
var _require2 = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs"),
|
var _require2 = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs"),
|
||||||
filterByTypes = _require2.filterByTypes,
|
filterByHtmlTokens = _require2.filterByHtmlTokens,
|
||||||
getHtmlTagInfo = _require2.getHtmlTagInfo;
|
getHtmlTagInfo = _require2.getHtmlTagInfo;
|
||||||
var nextLinesRe = /[\r\n][\s\S]*$/;
|
var nextLinesRe = /[\r\n][\s\S]*$/;
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
@ -4868,31 +4870,21 @@ module.exports = {
|
||||||
allowedElements = allowedElements.map(function (element) {
|
allowedElements = allowedElements.map(function (element) {
|
||||||
return element.toLowerCase();
|
return element.toLowerCase();
|
||||||
});
|
});
|
||||||
var pending = [params.parsers.micromark.tokens];
|
var _iterator = _createForOfIteratorHelper(filterByHtmlTokens(params.parsers.micromark.tokens)),
|
||||||
var current = null;
|
_step;
|
||||||
while (current = pending.shift()) {
|
try {
|
||||||
var tokens = current;
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
||||||
var _iterator = _createForOfIteratorHelper(filterByTypes(tokens, ["htmlFlow", "htmlText"])),
|
var token = _step.value;
|
||||||
_step;
|
var htmlTagInfo = getHtmlTagInfo(token);
|
||||||
try {
|
if (htmlTagInfo && !htmlTagInfo.close && !allowedElements.includes(htmlTagInfo.name.toLowerCase())) {
|
||||||
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
var range = [token.startColumn, token.text.replace(nextLinesRe, "").length];
|
||||||
var token = _step.value;
|
addError(onError, token.startLine, "Element: " + htmlTagInfo.name, undefined, range);
|
||||||
if (token.type === "htmlText") {
|
|
||||||
var htmlTagInfo = getHtmlTagInfo(token);
|
|
||||||
if (htmlTagInfo && !htmlTagInfo.close && !allowedElements.includes(htmlTagInfo.name.toLowerCase())) {
|
|
||||||
var range = [token.startColumn, token.text.replace(nextLinesRe, "").length];
|
|
||||||
addError(onError, token.startLine, "Element: " + htmlTagInfo.name, undefined, range);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// token.type === "htmlFlow"
|
|
||||||
pending.push(token.htmlFlowChildren);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
_iterator.e(err);
|
|
||||||
} finally {
|
|
||||||
_iterator.f();
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator.e(err);
|
||||||
|
} finally {
|
||||||
|
_iterator.f();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -6098,18 +6090,18 @@ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symb
|
||||||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
||||||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
||||||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
||||||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
||||||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
||||||
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
|
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
|
||||||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
||||||
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
||||||
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
||||||
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
||||||
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
|
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
|
||||||
addError = _require.addError,
|
addError = _require.addError,
|
||||||
addErrorDetailIf = _require.addErrorDetailIf,
|
addErrorDetailIf = _require.addErrorDetailIf;
|
||||||
escapeForRegExp = _require.escapeForRegExp,
|
var _require2 = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs"),
|
||||||
filterTokens = _require.filterTokens,
|
filterByHtmlTokens = _require2.filterByHtmlTokens,
|
||||||
forEachInlineChild = _require.forEachInlineChild,
|
filterByTypes = _require2.filterByTypes,
|
||||||
forEachHeading = _require.forEachHeading,
|
getHtmlTagInfo = _require2.getHtmlTagInfo;
|
||||||
htmlElementRe = _require.htmlElementRe;
|
|
||||||
|
|
||||||
// Regular expression for identifying HTML anchor names
|
// Regular expression for identifying HTML anchor names
|
||||||
var idRe = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]id[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*=[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*["']?((?:(?![\t-\r "'>\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uD800-\uDFFF\uFEFF])[\s\S]|[\uD800-\uDBFF][\uDC00-\uDFFF])+)/i;
|
var idRe = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]id[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*=[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*["']?((?:(?![\t-\r "'>\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uD800-\uDFFF\uFEFF])[\s\S]|[\uD800-\uDBFF][\uDC00-\uDFFF])+)/i;
|
||||||
|
|
@ -6120,14 +6112,12 @@ var anchorRe = /\{(#[0-9a-z]+(?:[\x2D_][0-9a-z]+)*)\}/g;
|
||||||
* 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} inline Inline token for heading.
|
* @param {Object} headingText Heading text token.
|
||||||
* @returns {string} Fragment string for heading.
|
* @returns {string} Fragment string for heading.
|
||||||
*/
|
*/
|
||||||
function convertHeadingToHTMLFragment(inline) {
|
function convertHeadingToHTMLFragment(headingText) {
|
||||||
var inlineText = inline.children.filter(function (token) {
|
var inlineText = filterByTypes(headingText.children, ["codeTextData", "data"]).map(function (token) {
|
||||||
return token.type !== "html_inline";
|
return token.text;
|
||||||
}).map(function (token) {
|
|
||||||
return token.content;
|
|
||||||
}).join("");
|
}).join("");
|
||||||
return "#" + encodeURIComponent(inlineText.toLowerCase()
|
return "#" + encodeURIComponent(inlineText.toLowerCase()
|
||||||
// RegExp source with Ruby's \p{Word} expanded into its General Categories
|
// RegExp source with Ruby's \p{Word} expanded into its General Categories
|
||||||
|
|
@ -6141,81 +6131,116 @@ module.exports = {
|
||||||
"description": "Link fragments should be valid",
|
"description": "Link fragments should be valid",
|
||||||
"tags": ["links"],
|
"tags": ["links"],
|
||||||
"function": function MD051(params, onError) {
|
"function": function MD051(params, onError) {
|
||||||
|
var tokens = params.parsers.micromark.tokens;
|
||||||
var fragments = new Map();
|
var fragments = new Map();
|
||||||
|
|
||||||
// Process headings
|
// Process headings
|
||||||
forEachHeading(params, function (heading, content, inline) {
|
var headingTexts = filterByTypes(tokens, ["atxHeadingText", "setextHeadingText"]);
|
||||||
var fragment = convertHeadingToHTMLFragment(inline);
|
var _iterator = _createForOfIteratorHelper(headingTexts),
|
||||||
var count = fragments.get(fragment) || 0;
|
_step;
|
||||||
if (count) {
|
try {
|
||||||
fragments.set("".concat(fragment, "-").concat(count), 0);
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
||||||
}
|
var headingText = _step.value;
|
||||||
fragments.set(fragment, count + 1);
|
var fragment = convertHeadingToHTMLFragment(headingText);
|
||||||
var match = null;
|
var count = fragments.get(fragment) || 0;
|
||||||
while ((match = anchorRe.exec(content)) !== null) {
|
if (count) {
|
||||||
var _match = match,
|
fragments.set("".concat(fragment, "-").concat(count), 0);
|
||||||
_match2 = _slicedToArray(_match, 2),
|
}
|
||||||
anchor = _match2[1];
|
fragments.set(fragment, count + 1);
|
||||||
if (!fragments.has(anchor)) {
|
var match = null;
|
||||||
fragments.set(anchor, 1);
|
while ((match = anchorRe.exec(headingText.text)) !== null) {
|
||||||
|
var _match = match,
|
||||||
|
_match2 = _slicedToArray(_match, 2),
|
||||||
|
anchor = _match2[1];
|
||||||
|
if (!fragments.has(anchor)) {
|
||||||
|
fragments.set(anchor, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
// Process HTML anchors
|
// Process HTML anchors
|
||||||
var processHtmlToken = function processHtmlToken(token) {
|
} catch (err) {
|
||||||
var match = null;
|
_iterator.e(err);
|
||||||
while ((match = htmlElementRe.exec(token.content)) !== null) {
|
} finally {
|
||||||
var _match3 = match,
|
_iterator.f();
|
||||||
_match4 = _slicedToArray(_match3, 3),
|
}
|
||||||
tag = _match4[0],
|
var _iterator2 = _createForOfIteratorHelper(filterByHtmlTokens(tokens)),
|
||||||
element = _match4[2];
|
_step2;
|
||||||
var anchorMatch = idRe.exec(tag) || element.toLowerCase() === "a" && nameRe.exec(tag);
|
try {
|
||||||
if (anchorMatch) {
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
||||||
fragments.set("#".concat(anchorMatch[1]), 0);
|
var token = _step2.value;
|
||||||
|
var htmlTagInfo = getHtmlTagInfo(token);
|
||||||
|
if (htmlTagInfo && !htmlTagInfo.close) {
|
||||||
|
var anchorMatch = idRe.exec(token.text) || htmlTagInfo.name.toLowerCase() === "a" && nameRe.exec(token.text);
|
||||||
|
if (anchorMatch) {
|
||||||
|
fragments.set("#".concat(anchorMatch[1]), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
filterTokens(params, "html_block", processHtmlToken);
|
// Process link and definition fragments
|
||||||
forEachInlineChild(params, "html_inline", processHtmlToken);
|
} catch (err) {
|
||||||
// Process link fragments
|
_iterator2.e(err);
|
||||||
forEachInlineChild(params, "link_open", function (token) {
|
} finally {
|
||||||
var attrs = token.attrs,
|
_iterator2.f();
|
||||||
lineNumber = token.lineNumber,
|
}
|
||||||
line = token.line;
|
var parentChilds = [["link", "resourceDestinationString"], ["definition", "definitionDestinationString"]];
|
||||||
var href = attrs.find(function (attr) {
|
for (var _i = 0, _parentChilds = parentChilds; _i < _parentChilds.length; _i++) {
|
||||||
return attr[0] === "href";
|
var _parentChilds$_i = _slicedToArray(_parentChilds[_i], 2),
|
||||||
});
|
parentType = _parentChilds$_i[0],
|
||||||
var id = href && href[1];
|
definitionType = _parentChilds$_i[1];
|
||||||
if (id && id.length > 1 && id[0] === "#" && !fragments.has(id)) {
|
var links = filterByTypes(tokens, [parentType]);
|
||||||
var context = id;
|
var _iterator3 = _createForOfIteratorHelper(links),
|
||||||
var range = null;
|
_step3;
|
||||||
var fixInfo = null;
|
try {
|
||||||
var match = line.match(new RegExp("\\[.*?\\]\\(".concat(escapeForRegExp(context), "\\)")));
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
||||||
if (match) {
|
var link = _step3.value;
|
||||||
var _match5 = _slicedToArray(match, 1);
|
var definitions = filterByTypes(link.children, [definitionType]);
|
||||||
context = _match5[0];
|
var _iterator4 = _createForOfIteratorHelper(definitions),
|
||||||
var index = match.index;
|
_step4;
|
||||||
var length = context.length;
|
try {
|
||||||
range = [index + 1, length];
|
var _loop = function _loop() {
|
||||||
fixInfo = {
|
var definition = _step4.value;
|
||||||
"editColumn": index + (length - id.length),
|
if (definition.text.length > 1 && definition.text.startsWith("#") && !fragments.has(definition.text)) {
|
||||||
"deleteCount": id.length,
|
// eslint-disable-next-line no-undef-init
|
||||||
"insertText": null
|
var range = undefined;
|
||||||
};
|
// eslint-disable-next-line no-undef-init
|
||||||
}
|
var fixInfo = undefined;
|
||||||
var idLower = id.toLowerCase();
|
if (link.startLine === link.endLine) {
|
||||||
var mixedCaseKey = _toConsumableArray(fragments.keys()).find(function (key) {
|
range = [link.startColumn, link.endColumn - link.startColumn];
|
||||||
return idLower === key.toLowerCase();
|
fixInfo = {
|
||||||
});
|
"editColumn": definition.startColumn,
|
||||||
if (mixedCaseKey) {
|
"deleteCount": definition.endColumn - definition.startColumn
|
||||||
(fixInfo || {}).insertText = mixedCaseKey;
|
};
|
||||||
addErrorDetailIf(onError, lineNumber, mixedCaseKey, id, undefined, context, range, fixInfo);
|
}
|
||||||
} else {
|
var definitionTextLower = definition.text.toLowerCase();
|
||||||
addError(onError, lineNumber, undefined, context,
|
var mixedCaseKey = _toConsumableArray(fragments.keys()).find(function (key) {
|
||||||
// @ts-ignore
|
return definitionTextLower === key.toLowerCase();
|
||||||
range);
|
});
|
||||||
|
if (mixedCaseKey) {
|
||||||
|
// @ts-ignore
|
||||||
|
(fixInfo || {}).insertText = mixedCaseKey;
|
||||||
|
addErrorDetailIf(onError, link.startLine, mixedCaseKey, definition.text, undefined, link.text, range, fixInfo);
|
||||||
|
} else {
|
||||||
|
addError(onError, link.startLine, undefined, link.text, range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
||||||
|
_loop();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator4.e(err);
|
||||||
|
} finally {
|
||||||
|
_iterator4.f();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator3.e(err);
|
||||||
|
} finally {
|
||||||
|
_iterator3.f();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ letters, numbers, `-`, and `_`):
|
||||||
[Link](#custom-name)
|
[Link](#custom-name)
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, an HTML `a` tag with an `id` or a `name` attribute can be used to
|
Alternatively, any HTML tag with an `id` attribute or an `a` tag with a `name`
|
||||||
define a fragment:
|
attribute can be used to define a fragment:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
<a id="bookmark"></a>
|
<a id="bookmark"></a>
|
||||||
|
|
|
||||||
|
|
@ -2176,8 +2176,8 @@ letters, numbers, `-`, and `_`):
|
||||||
[Link](#custom-name)
|
[Link](#custom-name)
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, an HTML `a` tag with an `id` or a `name` attribute can be used to
|
Alternatively, any HTML tag with an `id` attribute or an `a` tag with a `name`
|
||||||
define a fragment:
|
attribute can be used to define a fragment:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
<a id="bookmark"></a>
|
<a id="bookmark"></a>
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ letters, numbers, `-`, and `_`):
|
||||||
[Link](#custom-name)
|
[Link](#custom-name)
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, an HTML `a` tag with an `id` or a `name` attribute can be used to
|
Alternatively, any HTML tag with an `id` attribute or an `a` tag with a `name`
|
||||||
define a fragment:
|
attribute can be used to define a fragment:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
<a id="bookmark"></a>
|
<a id="bookmark"></a>
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,6 @@ const inlineCommentStartRe =
|
||||||
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi;
|
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi;
|
||||||
module.exports.inlineCommentStartRe = inlineCommentStartRe;
|
module.exports.inlineCommentStartRe = inlineCommentStartRe;
|
||||||
|
|
||||||
// Regular expression for matching HTML elements
|
|
||||||
const htmlElementRe = /<(([A-Za-z][A-Za-z\d-]*)(?:\s[^`>]*)?)\/?>/g;
|
|
||||||
module.exports.htmlElementRe = htmlElementRe;
|
|
||||||
|
|
||||||
// Regular expressions for range matching
|
// Regular expressions for range matching
|
||||||
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/;
|
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/;
|
||||||
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/;
|
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/;
|
||||||
|
|
@ -444,23 +440,6 @@ module.exports.flattenLists = function flattenLists(tokens) {
|
||||||
return flattenedLists;
|
return flattenedLists;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the provided function for each specified inline child token.
|
|
||||||
*
|
|
||||||
* @param {Object} params RuleParams instance.
|
|
||||||
* @param {string} type Token type identifier.
|
|
||||||
* @param {Function} handler Callback function.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
function forEachInlineChild(params, type, handler) {
|
|
||||||
filterTokens(params, "inline", (token) => {
|
|
||||||
for (const child of token.children.filter((c) => c.type === type)) {
|
|
||||||
handler(child, token);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
module.exports.forEachInlineChild = forEachInlineChild;
|
|
||||||
|
|
||||||
// Calls the provided function for each heading's content
|
// Calls the provided function for each heading's content
|
||||||
module.exports.forEachHeading = function forEachHeading(params, handler) {
|
module.exports.forEachHeading = function forEachHeading(params, handler) {
|
||||||
let heading = null;
|
let heading = null;
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,30 @@ function filterByTypes(tokens, allowed) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a list of Micromark tokens for HTML tokens.
|
||||||
|
*
|
||||||
|
* @param {Token[]} tokens Micromark tokens.
|
||||||
|
* @returns {Token[]} Filtered tokens.
|
||||||
|
*/
|
||||||
|
function filterByHtmlTokens(tokens) {
|
||||||
|
const result = [];
|
||||||
|
const pending = [ tokens ];
|
||||||
|
let current = null;
|
||||||
|
while ((current = pending.shift())) {
|
||||||
|
for (const token of filterByTypes(current, [ "htmlFlow", "htmlText" ])) {
|
||||||
|
if (token.type === "htmlText") {
|
||||||
|
result.push(token);
|
||||||
|
} else {
|
||||||
|
// token.type === "htmlFlow"
|
||||||
|
// @ts-ignore
|
||||||
|
pending.push(token.htmlFlowChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all nested child tokens.
|
* Returns a list of all nested child tokens.
|
||||||
*
|
*
|
||||||
|
|
@ -293,6 +317,7 @@ function tokenIfType(token, type) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"parse": micromarkParse,
|
"parse": micromarkParse,
|
||||||
|
filterByHtmlTokens,
|
||||||
filterByPredicate,
|
filterByPredicate,
|
||||||
filterByTypes,
|
filterByTypes,
|
||||||
flattenedChildren,
|
flattenedChildren,
|
||||||
|
|
|
||||||
49
lib/md033.js
49
lib/md033.js
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError } = require("../helpers");
|
const { addError } = require("../helpers");
|
||||||
const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
|
const { filterByHtmlTokens, getHtmlTagInfo } =
|
||||||
|
require("../helpers/micromark.cjs");
|
||||||
|
|
||||||
const nextLinesRe = /[\r\n][\s\S]*$/;
|
const nextLinesRe = /[\r\n][\s\S]*$/;
|
||||||
|
|
||||||
|
|
@ -15,34 +16,24 @@ module.exports = {
|
||||||
let allowedElements = params.config.allowed_elements;
|
let allowedElements = params.config.allowed_elements;
|
||||||
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
|
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
|
||||||
allowedElements = allowedElements.map((element) => element.toLowerCase());
|
allowedElements = allowedElements.map((element) => element.toLowerCase());
|
||||||
const pending = [ params.parsers.micromark.tokens ];
|
for (const token of filterByHtmlTokens(params.parsers.micromark.tokens)) {
|
||||||
let current = null;
|
const htmlTagInfo = getHtmlTagInfo(token);
|
||||||
while ((current = pending.shift())) {
|
if (
|
||||||
const tokens = current;
|
htmlTagInfo &&
|
||||||
for (const token of filterByTypes(tokens, [ "htmlFlow", "htmlText" ])) {
|
!htmlTagInfo.close &&
|
||||||
if (token.type === "htmlText") {
|
!allowedElements.includes(htmlTagInfo.name.toLowerCase())
|
||||||
const htmlTagInfo = getHtmlTagInfo(token);
|
) {
|
||||||
if (
|
const range = [
|
||||||
htmlTagInfo &&
|
token.startColumn,
|
||||||
!htmlTagInfo.close &&
|
token.text.replace(nextLinesRe, "").length
|
||||||
!allowedElements.includes(htmlTagInfo.name.toLowerCase())
|
];
|
||||||
) {
|
addError(
|
||||||
const range = [
|
onError,
|
||||||
token.startColumn,
|
token.startLine,
|
||||||
token.text.replace(nextLinesRe, "").length
|
"Element: " + htmlTagInfo.name,
|
||||||
];
|
undefined,
|
||||||
addError(
|
range
|
||||||
onError,
|
);
|
||||||
token.startLine,
|
|
||||||
"Element: " + htmlTagInfo.name,
|
|
||||||
undefined,
|
|
||||||
range
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// token.type === "htmlFlow"
|
|
||||||
pending.push(token.htmlFlowChildren);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
149
lib/md051.js
149
lib/md051.js
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, addErrorDetailIf, escapeForRegExp, filterTokens,
|
const { addError, addErrorDetailIf } = require("../helpers");
|
||||||
forEachInlineChild, forEachHeading, htmlElementRe } = require("../helpers");
|
const { filterByHtmlTokens, filterByTypes, getHtmlTagInfo } =
|
||||||
|
require("../helpers/micromark.cjs");
|
||||||
|
|
||||||
// Regular expression for identifying HTML anchor names
|
// Regular expression for identifying HTML anchor names
|
||||||
const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
|
const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
|
||||||
|
|
@ -14,14 +15,14 @@ const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
|
||||||
* 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} inline Inline token for heading.
|
* @param {Object} headingText Heading text token.
|
||||||
* @returns {string} Fragment string for heading.
|
* @returns {string} Fragment string for heading.
|
||||||
*/
|
*/
|
||||||
function convertHeadingToHTMLFragment(inline) {
|
function convertHeadingToHTMLFragment(headingText) {
|
||||||
const inlineText = inline.children
|
const inlineText =
|
||||||
.filter((token) => token.type !== "html_inline")
|
filterByTypes(headingText.children, [ "codeTextData", "data" ])
|
||||||
.map((token) => token.content)
|
.map((token) => token.text)
|
||||||
.join("");
|
.join("");
|
||||||
return "#" + encodeURIComponent(
|
return "#" + encodeURIComponent(
|
||||||
inlineText
|
inlineText
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
|
@ -42,86 +43,96 @@ module.exports = {
|
||||||
"description": "Link fragments should be valid",
|
"description": "Link fragments should be valid",
|
||||||
"tags": [ "links" ],
|
"tags": [ "links" ],
|
||||||
"function": function MD051(params, onError) {
|
"function": function MD051(params, onError) {
|
||||||
|
const { tokens } = params.parsers.micromark;
|
||||||
const fragments = new Map();
|
const fragments = new Map();
|
||||||
|
|
||||||
// Process headings
|
// Process headings
|
||||||
forEachHeading(params, (heading, content, inline) => {
|
const headingTexts = filterByTypes(
|
||||||
const fragment = convertHeadingToHTMLFragment(inline);
|
tokens,
|
||||||
|
[ "atxHeadingText", "setextHeadingText" ]
|
||||||
|
);
|
||||||
|
for (const headingText of headingTexts) {
|
||||||
|
const fragment = convertHeadingToHTMLFragment(headingText);
|
||||||
const count = fragments.get(fragment) || 0;
|
const count = fragments.get(fragment) || 0;
|
||||||
if (count) {
|
if (count) {
|
||||||
fragments.set(`${fragment}-${count}`, 0);
|
fragments.set(`${fragment}-${count}`, 0);
|
||||||
}
|
}
|
||||||
fragments.set(fragment, count + 1);
|
fragments.set(fragment, count + 1);
|
||||||
let match = null;
|
let match = null;
|
||||||
while ((match = anchorRe.exec(content)) !== null) {
|
while ((match = anchorRe.exec(headingText.text)) !== null) {
|
||||||
const [ , anchor ] = match;
|
const [ , anchor ] = match;
|
||||||
if (!fragments.has(anchor)) {
|
if (!fragments.has(anchor)) {
|
||||||
fragments.set(anchor, 1);
|
fragments.set(anchor, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// Process HTML anchors
|
// Process HTML anchors
|
||||||
const processHtmlToken = (token) => {
|
for (const token of filterByHtmlTokens(tokens)) {
|
||||||
let match = null;
|
const htmlTagInfo = getHtmlTagInfo(token);
|
||||||
while ((match = htmlElementRe.exec(token.content)) !== null) {
|
if (htmlTagInfo && !htmlTagInfo.close) {
|
||||||
const [ tag, , element ] = match;
|
const anchorMatch = idRe.exec(token.text) ||
|
||||||
const anchorMatch = idRe.exec(tag) ||
|
(htmlTagInfo.name.toLowerCase() === "a" && nameRe.exec(token.text));
|
||||||
(element.toLowerCase() === "a" && nameRe.exec(tag));
|
|
||||||
if (anchorMatch) {
|
if (anchorMatch) {
|
||||||
fragments.set(`#${anchorMatch[1]}`, 0);
|
fragments.set(`#${anchorMatch[1]}`, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
filterTokens(params, "html_block", processHtmlToken);
|
|
||||||
forEachInlineChild(params, "html_inline", processHtmlToken);
|
// Process link and definition fragments
|
||||||
// Process link fragments
|
const parentChilds = [
|
||||||
forEachInlineChild(params, "link_open", (token) => {
|
[ "link", "resourceDestinationString" ],
|
||||||
const { attrs, lineNumber, line } = token;
|
[ "definition", "definitionDestinationString" ]
|
||||||
const href = attrs.find((attr) => attr[0] === "href");
|
];
|
||||||
const id = href && href[1];
|
for (const [ parentType, definitionType ] of parentChilds) {
|
||||||
if (id && (id.length > 1) && (id[0] === "#") && !fragments.has(id)) {
|
const links = filterByTypes(tokens, [ parentType ]);
|
||||||
let context = id;
|
for (const link of links) {
|
||||||
let range = null;
|
const definitions = filterByTypes(link.children, [ definitionType ]);
|
||||||
let fixInfo = null;
|
for (const definition of definitions) {
|
||||||
const match = line.match(
|
if (
|
||||||
new RegExp(`\\[.*?\\]\\(${escapeForRegExp(context)}\\)`)
|
(definition.text.length > 1) &&
|
||||||
);
|
definition.text.startsWith("#") &&
|
||||||
if (match) {
|
!fragments.has(definition.text)
|
||||||
[ context ] = match;
|
) {
|
||||||
const index = match.index;
|
// eslint-disable-next-line no-undef-init
|
||||||
const length = context.length;
|
let range = undefined;
|
||||||
range = [ index + 1, length ];
|
// eslint-disable-next-line no-undef-init
|
||||||
fixInfo = {
|
let fixInfo = undefined;
|
||||||
"editColumn": index + (length - id.length),
|
if (link.startLine === link.endLine) {
|
||||||
"deleteCount": id.length,
|
range = [ link.startColumn, link.endColumn - link.startColumn ];
|
||||||
"insertText": null
|
fixInfo = {
|
||||||
};
|
"editColumn": definition.startColumn,
|
||||||
}
|
"deleteCount": definition.endColumn - definition.startColumn
|
||||||
const idLower = id.toLowerCase();
|
};
|
||||||
const mixedCaseKey = [ ...fragments.keys() ]
|
}
|
||||||
.find((key) => idLower === key.toLowerCase());
|
const definitionTextLower = definition.text.toLowerCase();
|
||||||
if (mixedCaseKey) {
|
const mixedCaseKey = [ ...fragments.keys() ]
|
||||||
(fixInfo || {}).insertText = mixedCaseKey;
|
.find((key) => definitionTextLower === key.toLowerCase());
|
||||||
addErrorDetailIf(
|
if (mixedCaseKey) {
|
||||||
onError,
|
// @ts-ignore
|
||||||
lineNumber,
|
(fixInfo || {}).insertText = mixedCaseKey;
|
||||||
mixedCaseKey,
|
addErrorDetailIf(
|
||||||
id,
|
onError,
|
||||||
undefined,
|
link.startLine,
|
||||||
context,
|
mixedCaseKey,
|
||||||
range,
|
definition.text,
|
||||||
fixInfo
|
undefined,
|
||||||
);
|
link.text,
|
||||||
} else {
|
range,
|
||||||
addError(
|
fixInfo
|
||||||
onError,
|
);
|
||||||
lineNumber,
|
} else {
|
||||||
undefined,
|
addError(
|
||||||
context,
|
onError,
|
||||||
// @ts-ignore
|
link.startLine,
|
||||||
range
|
undefined,
|
||||||
);
|
link.text,
|
||||||
|
range
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
[Valid](#valid-heading-with-emphasis)
|
[Valid](#valid-heading-with-emphasis)
|
||||||
|
|
||||||
|
[Valid](#valid-heading-with-code)
|
||||||
|
|
||||||
[Valid](#valid-heading-with-quotes--and-double-quotes-)
|
[Valid](#valid-heading-with-quotes--and-double-quotes-)
|
||||||
|
|
||||||
[Valid](#-valid-heading-with-emoji)
|
[Valid](#-valid-heading-with-emoji)
|
||||||
|
|
@ -70,6 +72,10 @@ Text
|
||||||
|
|
||||||
Text
|
Text
|
||||||
|
|
||||||
|
### Valid Heading With `Code`
|
||||||
|
|
||||||
|
Text
|
||||||
|
|
||||||
### Valid Heading With Quotes ' And Double Quotes "
|
### Valid Heading With Quotes ' And Double Quotes "
|
||||||
|
|
||||||
Text
|
Text
|
||||||
|
|
@ -157,9 +163,12 @@ Text
|
||||||
|
|
||||||
[Invalid](#not-an-id-should-be-ignored) {MD051}
|
[Invalid](#not-an-id-should-be-ignored) {MD051}
|
||||||
|
|
||||||
[Invalid][badref] {MD051}
|
[Invalid {MD051}](#multi-line
|
||||||
|
"Title")
|
||||||
|
|
||||||
[badref]: #missing
|
[Invalid][badref]
|
||||||
|
|
||||||
|
[badref]: #missing "{MD051}"
|
||||||
|
|
||||||
## Inconsistent Case Fragments
|
## Inconsistent Case Fragments
|
||||||
|
|
||||||
|
|
@ -167,9 +176,12 @@ Text
|
||||||
|
|
||||||
[ALL CAPS](#NAMEDLINK) {MD051}
|
[ALL CAPS](#NAMEDLINK) {MD051}
|
||||||
|
|
||||||
[MiXeD][mixedref] {MD051}
|
[Multi-line {MD051}](#NAMEDLINK
|
||||||
|
"Title")
|
||||||
|
|
||||||
[mixedref]: #idLINK
|
[MiXeD][mixedref]
|
||||||
|
|
||||||
|
[mixedref]: #idLINK "{MD051}"
|
||||||
|
|
||||||
## Valid Named Fragments
|
## Valid Named Fragments
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,10 @@ Generated by [AVA](https://avajs.dev).
|
||||||
> Expected linting violations
|
> Expected linting violations
|
||||||
|
|
||||||
`test-repos/mochajs-mocha/.github/CODE_OF_CONDUCT.md: 58: MD034/no-bare-urls Bare URL used [Context: "report@lists.openjsf.org"]␊
|
`test-repos/mochajs-mocha/.github/CODE_OF_CONDUCT.md: 58: MD034/no-bare-urls Bare URL used [Context: "report@lists.openjsf.org"]␊
|
||||||
test-repos/mochajs-mocha/.github/CONTRIBUTING.md: 11: MD051/link-fragments Link fragments should be valid [Context: "[search](https://github.com/mochajs/mocha/issues/) to see if it's already been reported**. Otherwise, create a [new issue](https://github.com/mochajs/mocha/issues/new). If you can fix the bug yourself, feel free to create a [pull request](#propose-a-change)"]␊
|
test-repos/mochajs-mocha/.github/CONTRIBUTING.md: 11: MD051/link-fragments Link fragments should be valid [Context: "[pull request](#propose-a-change)"]␊
|
||||||
test-repos/mochajs-mocha/.github/CONTRIBUTING.md: 41: MD051/link-fragments Link fragments should be valid [Context: "[ask for help](#got-a-question)"]␊
|
test-repos/mochajs-mocha/.github/CONTRIBUTING.md: 41: MD051/link-fragments Link fragments should be valid [Context: "[ask for help](#got-a-question)"]␊
|
||||||
test-repos/mochajs-mocha/MAINTAINERS.md: 34: MD051/link-fragments Link fragments should be valid [Context: "[Projects](#projects)"]␊
|
test-repos/mochajs-mocha/MAINTAINERS.md: 34: MD051/link-fragments Link fragments should be valid [Context: "[Projects](#projects)"]␊
|
||||||
test-repos/mochajs-mocha/PROJECT_CHARTER.md: 51: MD051/link-fragments Link fragments should be valid [Context: "[mochajs organization](https://github.com/mochajs) unless explicitly stated in [§2: Scope](#%c2%a72-scope)"]␊
|
test-repos/mochajs-mocha/PROJECT_CHARTER.md: 51: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊
|
||||||
test-repos/mochajs-mocha/PROJECT_CHARTER.md: 56: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊
|
test-repos/mochajs-mocha/PROJECT_CHARTER.md: 56: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 32: MD051/link-fragments Link fragments should be valid [Context: "[global variable leak detection](#-check-leaks)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 32: MD051/link-fragments Link fragments should be valid [Context: "[global variable leak detection](#-check-leaks)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 33: MD051/link-fragments Link fragments should be valid [Context: "[optionally run tests that match a regexp](#-grep-regexp-g-regexp)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 33: MD051/link-fragments Link fragments should be valid [Context: "[optionally run tests that match a regexp](#-grep-regexp-g-regexp)"]␊
|
||||||
|
|
@ -72,7 +72,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1257: MD051/link-fragments Link fragments should be valid [Context: "[\`--node-option\`](#-node-option-name-n-name)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1257: MD051/link-fragments Link fragments should be valid [Context: "[\`--node-option\`](#-node-option-name-n-name)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1263: MD051/link-fragments Link fragments should be valid [Context: "[\`--parallel\`](#-parallel-p)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1263: MD051/link-fragments Link fragments should be valid [Context: "[\`--parallel\`](#-parallel-p)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1288: MD051/link-fragments Link fragments should be valid [Context: "[\`--grep\`](#-grep-regexp-g-regexp)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1288: MD051/link-fragments Link fragments should be valid [Context: "[\`--grep\`](#-grep-regexp-g-regexp)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1288: MD051/link-fragments Link fragments should be valid [Context: "[\`--grep\`](#-grep-regexp-g-regexp) or [\`--fgrep\`](#-fgrep-string-f-string)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1288: MD051/link-fragments Link fragments should be valid [Context: "[\`--fgrep\`](#-fgrep-string-f-string)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1299: MD051/link-fragments Link fragments should be valid [Context: "[\`--file\`](#-file-filedirectoryglob)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1299: MD051/link-fragments Link fragments should be valid [Context: "[\`--file\`](#-file-filedirectoryglob)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1300: MD051/link-fragments Link fragments should be valid [Context: "[\`--sort\`](#-sort-s)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1300: MD051/link-fragments Link fragments should be valid [Context: "[\`--sort\`](#-sort-s)"]␊
|
||||||
test-repos/mochajs-mocha/docs/index.md: 1306: MD051/link-fragments Link fragments should be valid [Context: "[globally](#-timeout-ms-t-ms)"]␊
|
test-repos/mochajs-mocha/docs/index.md: 1306: MD051/link-fragments Link fragments should be valid [Context: "[globally](#-timeout-ms-t-ms)"]␊
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -23472,7 +23472,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
31,
|
31,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 144,
|
lineNumber: 150,
|
||||||
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: [
|
||||||
|
|
@ -23488,7 +23488,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
36,
|
36,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 146,
|
lineNumber: 152,
|
||||||
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: [
|
||||||
|
|
@ -23504,7 +23504,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
28,
|
28,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 148,
|
lineNumber: 154,
|
||||||
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: [
|
||||||
|
|
@ -23520,7 +23520,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
18,
|
18,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 150,
|
lineNumber: 156,
|
||||||
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: [
|
||||||
|
|
@ -23540,7 +23540,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
editColumn: 11,
|
editColumn: 11,
|
||||||
insertText: '#HREFandID',
|
insertText: '#HREFandID',
|
||||||
},
|
},
|
||||||
lineNumber: 152,
|
lineNumber: 158,
|
||||||
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: [
|
||||||
|
|
@ -23556,7 +23556,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
34,
|
34,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 154,
|
lineNumber: 160,
|
||||||
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: [
|
||||||
|
|
@ -23572,7 +23572,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
34,
|
34,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 156,
|
lineNumber: 162,
|
||||||
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: [
|
||||||
|
|
@ -23588,7 +23588,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
39,
|
39,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 158,
|
lineNumber: 164,
|
||||||
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: [
|
||||||
|
|
@ -23597,11 +23597,28 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#missing',
|
errorContext: `[Invalid {MD051}](#multi-line␊
|
||||||
|
"Title")`,
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: null,
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 160,
|
lineNumber: 166,
|
||||||
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
|
||||||
|
ruleNames: [
|
||||||
|
'MD051',
|
||||||
|
'link-fragments',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorContext: '[badref]: #missing "{MD051}"',
|
||||||
|
errorDetail: null,
|
||||||
|
errorRange: [
|
||||||
|
1,
|
||||||
|
28,
|
||||||
|
],
|
||||||
|
fixInfo: null,
|
||||||
|
lineNumber: 171,
|
||||||
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: [
|
||||||
|
|
@ -23621,7 +23638,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
editColumn: 9,
|
editColumn: 9,
|
||||||
insertText: '#valid-fragments',
|
insertText: '#valid-fragments',
|
||||||
},
|
},
|
||||||
lineNumber: 166,
|
lineNumber: 175,
|
||||||
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: [
|
||||||
|
|
@ -23641,7 +23658,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
editColumn: 12,
|
editColumn: 12,
|
||||||
insertText: '#namedlink',
|
insertText: '#namedlink',
|
||||||
},
|
},
|
||||||
lineNumber: 168,
|
lineNumber: 177,
|
||||||
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: [
|
||||||
|
|
@ -23650,11 +23667,32 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#idLINK',
|
errorContext: `[Multi-line {MD051}](#NAMEDLINK␊
|
||||||
errorDetail: 'Expected: #idlink; Actual: #idLINK',
|
"Title")`,
|
||||||
|
errorDetail: 'Expected: #namedlink; Actual: #NAMEDLINK',
|
||||||
errorRange: null,
|
errorRange: null,
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 170,
|
lineNumber: 179,
|
||||||
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md051.md',
|
||||||
|
ruleNames: [
|
||||||
|
'MD051',
|
||||||
|
'link-fragments',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorContext: '[mixedref]: #idLINK "{MD051}"',
|
||||||
|
errorDetail: 'Expected: #idlink; Actual: #idLINK',
|
||||||
|
errorRange: [
|
||||||
|
1,
|
||||||
|
29,
|
||||||
|
],
|
||||||
|
fixInfo: {
|
||||||
|
deleteCount: 7,
|
||||||
|
editColumn: 13,
|
||||||
|
insertText: '#idlink',
|
||||||
|
},
|
||||||
|
lineNumber: 184,
|
||||||
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: [
|
||||||
|
|
@ -23670,7 +23708,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
26,
|
26,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 207,
|
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: [
|
||||||
|
|
@ -23686,7 +23724,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
26,
|
26,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 209,
|
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: [
|
||||||
|
|
@ -23702,7 +23740,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
20,
|
20,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 211,
|
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: [
|
||||||
|
|
@ -23718,7 +23756,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
23,
|
23,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 213,
|
lineNumber: 225,
|
||||||
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: [
|
||||||
|
|
@ -23734,7 +23772,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
22,
|
22,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 215,
|
lineNumber: 227,
|
||||||
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: [
|
||||||
|
|
@ -23750,7 +23788,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
42,
|
42,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 217,
|
lineNumber: 229,
|
||||||
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: [
|
||||||
|
|
@ -23766,7 +23804,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
21,
|
21,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 219,
|
lineNumber: 231,
|
||||||
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: [
|
||||||
|
|
@ -23782,7 +23820,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
21,
|
21,
|
||||||
],
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 221,
|
lineNumber: 233,
|
||||||
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: [
|
||||||
|
|
@ -23805,6 +23843,8 @@ Generated by [AVA](https://avajs.dev).
|
||||||
␊
|
␊
|
||||||
[Valid](#valid-heading-with-emphasis)␊
|
[Valid](#valid-heading-with-emphasis)␊
|
||||||
␊
|
␊
|
||||||
|
[Valid](#valid-heading-with-code)␊
|
||||||
|
␊
|
||||||
[Valid](#valid-heading-with-quotes--and-double-quotes-)␊
|
[Valid](#valid-heading-with-quotes--and-double-quotes-)␊
|
||||||
␊
|
␊
|
||||||
[Valid](#-valid-heading-with-emoji)␊
|
[Valid](#-valid-heading-with-emoji)␊
|
||||||
|
|
@ -23863,6 +23903,10 @@ Generated by [AVA](https://avajs.dev).
|
||||||
␊
|
␊
|
||||||
Text␊
|
Text␊
|
||||||
␊
|
␊
|
||||||
|
### Valid Heading With \`Code\`␊
|
||||||
|
␊
|
||||||
|
Text␊
|
||||||
|
␊
|
||||||
### Valid Heading With Quotes ' And Double Quotes "␊
|
### Valid Heading With Quotes ' And Double Quotes "␊
|
||||||
␊
|
␊
|
||||||
Text␊
|
Text␊
|
||||||
|
|
@ -23950,9 +23994,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
␊
|
␊
|
||||||
[Invalid](#not-an-id-should-be-ignored) {MD051}␊
|
[Invalid](#not-an-id-should-be-ignored) {MD051}␊
|
||||||
␊
|
␊
|
||||||
[Invalid][badref] {MD051}␊
|
[Invalid {MD051}](#multi-line␊
|
||||||
|
"Title")␊
|
||||||
␊
|
␊
|
||||||
[badref]: #missing␊
|
[Invalid][badref]␊
|
||||||
|
␊
|
||||||
|
[badref]: #missing "{MD051}"␊
|
||||||
␊
|
␊
|
||||||
## Inconsistent Case Fragments␊
|
## Inconsistent Case Fragments␊
|
||||||
␊
|
␊
|
||||||
|
|
@ -23960,9 +24007,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
␊
|
␊
|
||||||
[ALL CAPS](#namedlink) {MD051}␊
|
[ALL CAPS](#namedlink) {MD051}␊
|
||||||
␊
|
␊
|
||||||
[MiXeD][mixedref] {MD051}␊
|
[Multi-line {MD051}](#NAMEDLINK␊
|
||||||
|
"Title")␊
|
||||||
␊
|
␊
|
||||||
[mixedref]: #idLINK␊
|
[MiXeD][mixedref]␊
|
||||||
|
␊
|
||||||
|
[mixedref]: #idlink "{MD051}"␊
|
||||||
␊
|
␊
|
||||||
## Valid Named Fragments␊
|
## Valid Named Fragments␊
|
||||||
␊
|
␊
|
||||||
|
|
@ -41804,9 +41854,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#link%60link',
|
errorContext: '[link](#link`link)',
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: [
|
||||||
|
6,
|
||||||
|
18,
|
||||||
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 81,
|
lineNumber: 81,
|
||||||
ruleDescription: 'Link fragments should be valid',
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
|
@ -41817,9 +41870,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#link%60link',
|
errorContext: '[link](#link`link)',
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: [
|
||||||
|
11,
|
||||||
|
18,
|
||||||
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 85,
|
lineNumber: 85,
|
||||||
ruleDescription: 'Link fragments should be valid',
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
|
@ -41830,9 +41886,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#link%60link',
|
errorContext: '[link(link](#link`link)',
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: [
|
||||||
|
6,
|
||||||
|
23,
|
||||||
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 87,
|
lineNumber: 87,
|
||||||
ruleDescription: 'Link fragments should be valid',
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
|
@ -41843,9 +41902,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#link%60link',
|
errorContext: '[link)link](#link`link)',
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: [
|
||||||
|
6,
|
||||||
|
23,
|
||||||
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 89,
|
lineNumber: 89,
|
||||||
ruleDescription: 'Link fragments should be valid',
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
|
@ -41856,9 +41918,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#link%5Blink%60link',
|
errorContext: '[link](#link[link`link)',
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: [
|
||||||
|
6,
|
||||||
|
23,
|
||||||
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 91,
|
lineNumber: 91,
|
||||||
ruleDescription: 'Link fragments should be valid',
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
|
@ -41869,9 +41934,12 @@ Generated by [AVA](https://avajs.dev).
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorContext: '#link%5Dlink%60link',
|
errorContext: '[link](#link]link`link)',
|
||||||
errorDetail: null,
|
errorDetail: null,
|
||||||
errorRange: null,
|
errorRange: [
|
||||||
|
6,
|
||||||
|
23,
|
||||||
|
],
|
||||||
fixInfo: null,
|
fixInfo: null,
|
||||||
lineNumber: 93,
|
lineNumber: 93,
|
||||||
ruleDescription: 'Link fragments should be valid',
|
ruleDescription: 'Link fragments should be valid',
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue