mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Cache all top-level calls to filterByTypes (~7% runtime reduction).
This commit is contained in:
parent
85e704f32a
commit
dfcb4529f3
47 changed files with 427 additions and 481 deletions
File diff suppressed because it is too large
Load diff
69
lib/cache.js
69
lib/cache.js
|
@ -2,14 +2,69 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const helpers = require("../helpers");
|
||||||
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
||||||
|
|
||||||
|
/** @type {Map<string, object>} */
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
|
// eslint-disable-next-line no-undef-init
|
||||||
|
let params = undefined;
|
||||||
|
|
||||||
module.exports.set = (keyValuePairs) => {
|
/**
|
||||||
for (const [ key, value ] of Object.entries(keyValuePairs)) {
|
* Initializes (resets) the cache.
|
||||||
map.set(key, value);
|
*
|
||||||
|
* @param {import("./markdownlint").RuleParams} [p] Rule parameters object.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function initialize(p) {
|
||||||
|
map.clear();
|
||||||
|
params = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a cached object value - computes it and caches it.
|
||||||
|
*
|
||||||
|
* @param {string} name Cache object name.
|
||||||
|
* @param {Function} getValue Getter for object value.
|
||||||
|
* @returns {Object} Object value.
|
||||||
|
*/
|
||||||
|
function getCached(name, getValue) {
|
||||||
|
if (map.has(name)) {
|
||||||
|
return map.get(name);
|
||||||
}
|
}
|
||||||
};
|
const value = getValue();
|
||||||
module.exports.clear = () => map.clear();
|
map.set(name, value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.referenceLinkImageData =
|
/**
|
||||||
() => map.get("referenceLinkImageData");
|
* Filters a list of Micromark tokens by type and caches the result.
|
||||||
|
*
|
||||||
|
* @param {import("./markdownlint").MicromarkTokenType[]} types Types to allow.
|
||||||
|
* @param {boolean} [htmlFlow] Whether to include htmlFlow content.
|
||||||
|
* @returns {import("./markdownlint").MicromarkToken[]} Filtered tokens.
|
||||||
|
*/
|
||||||
|
function filterByTypesCached(types, htmlFlow) {
|
||||||
|
return getCached(
|
||||||
|
types.join("|"),
|
||||||
|
() => filterByTypes(params.parsers.micromark.tokens, types, htmlFlow)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a reference link and image data object.
|
||||||
|
*
|
||||||
|
* @returns {Object} Reference link and image data object.
|
||||||
|
*/
|
||||||
|
function getReferenceLinkImageData() {
|
||||||
|
return getCached(
|
||||||
|
getReferenceLinkImageData.name,
|
||||||
|
() => helpers.getReferenceLinkImageData(params.parsers.micromark.tokens)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initialize,
|
||||||
|
filterByTypesCached,
|
||||||
|
getReferenceLinkImageData
|
||||||
|
};
|
||||||
|
|
|
@ -604,14 +604,13 @@ function lintContent(
|
||||||
const parsersNone = Object.freeze({});
|
const parsersNone = Object.freeze({});
|
||||||
const paramsBase = {
|
const paramsBase = {
|
||||||
name,
|
name,
|
||||||
"parsers": parsersMarkdownIt,
|
|
||||||
"lines": Object.freeze(lines),
|
"lines": Object.freeze(lines),
|
||||||
"frontMatterLines": Object.freeze(frontMatterLines)
|
"frontMatterLines": Object.freeze(frontMatterLines)
|
||||||
};
|
};
|
||||||
const referenceLinkImageData =
|
cache.initialize({
|
||||||
helpers.getReferenceLinkImageData(micromarkTokens);
|
...paramsBase,
|
||||||
cache.set({
|
"parsers": parsersMicromark,
|
||||||
referenceLinkImageData
|
"config": null
|
||||||
});
|
});
|
||||||
// Function to run for each rule
|
// Function to run for each rule
|
||||||
let results = [];
|
let results = [];
|
||||||
|
@ -826,7 +825,7 @@ function lintContent(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
callbackError(error);
|
callbackError(error);
|
||||||
} finally {
|
} finally {
|
||||||
cache.clear();
|
cache.initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes, getHeadingLevel } = require("../helpers/micromark.cjs");
|
const { getHeadingLevel } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -14,11 +15,7 @@ module.exports = {
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD001(params, onError) {
|
"function": function MD001(params, onError) {
|
||||||
let prevLevel = Number.MAX_SAFE_INTEGER;
|
let prevLevel = Number.MAX_SAFE_INTEGER;
|
||||||
const headings = filterByTypes(
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
|
||||||
const level = getHeadingLevel(heading);
|
const level = getHeadingLevel(heading);
|
||||||
if (level > prevLevel) {
|
if (level > prevLevel) {
|
||||||
addErrorDetailIf(
|
addErrorDetailIf(
|
||||||
|
|
10
lib/md003.js
10
lib/md003.js
|
@ -3,8 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes, getHeadingLevel, getHeadingStyle } =
|
const { getHeadingLevel, getHeadingStyle } = require("../helpers/micromark.cjs");
|
||||||
require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -15,11 +15,7 @@ module.exports = {
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD003(params, onError) {
|
"function": function MD003(params, onError) {
|
||||||
let style = String(params.config.style || "consistent");
|
let style = String(params.config.style || "consistent");
|
||||||
const headings = filterByTypes(
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
|
||||||
const styleForToken = getHeadingStyle(heading);
|
const styleForToken = getHeadingStyle(heading);
|
||||||
if (style === "consistent") {
|
if (style === "consistent") {
|
||||||
style = styleForToken;
|
style = styleForToken;
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes, getDescendantsByType, getTokenParentOfType } = require("../helpers/micromark.cjs");
|
const { getDescendantsByType, getTokenParentOfType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const markerToStyle = {
|
const markerToStyle = {
|
||||||
"-": "dash",
|
"-": "dash",
|
||||||
|
@ -39,11 +40,12 @@ module.exports = {
|
||||||
const style = String(params.config.style || "consistent");
|
const style = String(params.config.style || "consistent");
|
||||||
let expectedStyle = validStyles.has(style) ? style : "dash";
|
let expectedStyle = validStyles.has(style) ? style : "dash";
|
||||||
const nestingStyles = [];
|
const nestingStyles = [];
|
||||||
for (const listUnordered of filterByTypes(params.parsers.micromark.tokens, [ "listUnordered" ])) {
|
for (const listUnordered of filterByTypesCached([ "listUnordered" ])) {
|
||||||
let nesting = 0;
|
let nesting = 0;
|
||||||
if (style === "sublist") {
|
if (style === "sublist") {
|
||||||
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
||||||
let parent = listUnordered;
|
let parent = listUnordered;
|
||||||
|
// @ts-ignore
|
||||||
while ((parent = getTokenParentOfType(parent, [ "listOrdered", "listUnordered" ]))) {
|
while ((parent = getTokenParentOfType(parent, [ "listOrdered", "listUnordered" ]))) {
|
||||||
nesting++;
|
nesting++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, addErrorDetailIf } = require("../helpers");
|
const { addError, addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -13,11 +13,7 @@ module.exports = {
|
||||||
"tags": [ "bullet", "ul", "indentation" ],
|
"tags": [ "bullet", "ul", "indentation" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD005(params, onError) {
|
"function": function MD005(params, onError) {
|
||||||
const lists = filterByTypes(
|
for (const list of filterByTypesCached([ "listOrdered", "listUnordered" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "listOrdered", "listUnordered" ]
|
|
||||||
);
|
|
||||||
for (const list of lists) {
|
|
||||||
const expectedIndent = list.startColumn - 1;
|
const expectedIndent = list.startColumn - 1;
|
||||||
let expectedEnd = 0;
|
let expectedEnd = 0;
|
||||||
let endMatching = false;
|
let endMatching = false;
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes, getTokenParentOfType } = require("../helpers/micromark.cjs");
|
const { getTokenParentOfType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("markdownlint-micromark").TokenType[] */
|
/** @type import("markdownlint-micromark").TokenType[] */
|
||||||
|
@ -27,10 +28,7 @@ module.exports = {
|
||||||
const startIndent = Number(params.config.start_indent || indent);
|
const startIndent = Number(params.config.start_indent || indent);
|
||||||
const unorderedListNesting = new Map();
|
const unorderedListNesting = new Map();
|
||||||
let lastBlockQuotePrefix = null;
|
let lastBlockQuotePrefix = null;
|
||||||
const tokens = filterByTypes(
|
const tokens = filterByTypesCached(unorderedListTypes);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
unorderedListTypes
|
|
||||||
);
|
|
||||||
for (const token of tokens) {
|
for (const token of tokens) {
|
||||||
const { endColumn, parent, startColumn, startLine, type } = token;
|
const { endColumn, parent, startColumn, startLine, type } = token;
|
||||||
if (type === "blockQuotePrefix") {
|
if (type === "blockQuotePrefix") {
|
||||||
|
@ -40,6 +38,7 @@ module.exports = {
|
||||||
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
||||||
let current = token;
|
let current = token;
|
||||||
while (
|
while (
|
||||||
|
// @ts-ignore
|
||||||
(current = getTokenParentOfType(current, unorderedParentTypes))
|
(current = getTokenParentOfType(current, unorderedParentTypes))
|
||||||
) {
|
) {
|
||||||
if (current.type === "listUnordered") {
|
if (current.type === "listUnordered") {
|
||||||
|
|
14
lib/md009.js
14
lib/md009.js
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError } = require("../helpers");
|
const { addError } = require("../helpers");
|
||||||
const { addRangeToSet, filterByTypes } = require("../helpers/micromark.cjs");
|
const { addRangeToSet } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -17,17 +18,16 @@ module.exports = {
|
||||||
brSpaces = Number((brSpaces === undefined) ? 2 : brSpaces);
|
brSpaces = Number((brSpaces === undefined) ? 2 : brSpaces);
|
||||||
const listItemEmptyLines = !!params.config.list_item_empty_lines;
|
const listItemEmptyLines = !!params.config.list_item_empty_lines;
|
||||||
const strict = !!params.config.strict;
|
const strict = !!params.config.strict;
|
||||||
const { tokens } = params.parsers.micromark;
|
|
||||||
const codeBlockLineNumbers = new Set();
|
const codeBlockLineNumbers = new Set();
|
||||||
for (const codeBlock of filterByTypes(tokens, [ "codeFenced" ])) {
|
for (const codeBlock of filterByTypesCached([ "codeFenced" ])) {
|
||||||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine + 1, codeBlock.endLine - 1);
|
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine + 1, codeBlock.endLine - 1);
|
||||||
}
|
}
|
||||||
for (const codeBlock of filterByTypes(tokens, [ "codeIndented" ])) {
|
for (const codeBlock of filterByTypesCached([ "codeIndented" ])) {
|
||||||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
||||||
}
|
}
|
||||||
const listItemLineNumbers = new Set();
|
const listItemLineNumbers = new Set();
|
||||||
if (listItemEmptyLines) {
|
if (listItemEmptyLines) {
|
||||||
for (const listBlock of filterByTypes(tokens, [ "listOrdered", "listUnordered" ])) {
|
for (const listBlock of filterByTypesCached([ "listOrdered", "listUnordered" ])) {
|
||||||
addRangeToSet(listItemLineNumbers, listBlock.startLine, listBlock.endLine);
|
addRangeToSet(listItemLineNumbers, listBlock.startLine, listBlock.endLine);
|
||||||
let trailingIndent = true;
|
let trailingIndent = true;
|
||||||
for (let i = listBlock.children.length - 1; i >= 0; i--) {
|
for (let i = listBlock.children.length - 1; i >= 0; i--) {
|
||||||
|
@ -53,10 +53,10 @@ module.exports = {
|
||||||
const paragraphLineNumbers = new Set();
|
const paragraphLineNumbers = new Set();
|
||||||
const codeInlineLineNumbers = new Set();
|
const codeInlineLineNumbers = new Set();
|
||||||
if (strict) {
|
if (strict) {
|
||||||
for (const paragraph of filterByTypes(tokens, [ "paragraph" ])) {
|
for (const paragraph of filterByTypesCached([ "paragraph" ])) {
|
||||||
addRangeToSet(paragraphLineNumbers, paragraph.startLine, paragraph.endLine - 1);
|
addRangeToSet(paragraphLineNumbers, paragraph.startLine, paragraph.endLine - 1);
|
||||||
}
|
}
|
||||||
for (const codeText of filterByTypes(tokens, [ "codeText" ])) {
|
for (const codeText of filterByTypesCached([ "codeText" ])) {
|
||||||
addRangeToSet(codeInlineLineNumbers, codeText.startLine, codeText.endLine - 1);
|
addRangeToSet(codeInlineLineNumbers, codeText.startLine, codeText.endLine - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, withinAnyRange } = require("../helpers");
|
const { addError, withinAnyRange } = require("../helpers");
|
||||||
const { filterByTypes, getDescendantsByType, getExclusionsForToken } = require("../helpers/micromark.cjs");
|
const { getDescendantsByType, getExclusionsForToken } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const tabRe = /\t+/g;
|
const tabRe = /\t+/g;
|
||||||
|
|
||||||
|
@ -36,10 +37,7 @@ module.exports = {
|
||||||
} else {
|
} else {
|
||||||
exclusionTypes.push("codeFenced", "codeIndented", "codeText");
|
exclusionTypes.push("codeFenced", "codeIndented", "codeText");
|
||||||
}
|
}
|
||||||
const codeTokens = filterByTypes(
|
const codeTokens = filterByTypesCached(exclusionTypes).filter((token) => {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
exclusionTypes
|
|
||||||
).filter((token) => {
|
|
||||||
if ((token.type === "codeFenced") && (ignoreCodeLanguages.size > 0)) {
|
if ((token.type === "codeFenced") && (ignoreCodeLanguages.size > 0)) {
|
||||||
const fenceInfos = getDescendantsByType(token, [ "codeFencedFence", "codeFencedFenceInfo" ]);
|
const fenceInfos = getDescendantsByType(token, [ "codeFencedFence", "codeFencedFenceInfo" ]);
|
||||||
return fenceInfos.every((fenceInfo) => ignoreCodeLanguages.has(fenceInfo.text.toLowerCase()));
|
return fenceInfos.every((fenceInfo) => ignoreCodeLanguages.has(fenceInfo.text.toLowerCase()));
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, withinAnyRange } = require("../helpers");
|
const { addError, withinAnyRange } = require("../helpers");
|
||||||
const { addRangeToSet, getExclusionsForToken, filterByTypes } = require("../helpers/micromark.cjs");
|
const { addRangeToSet, getExclusionsForToken } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const reversedLinkRe =
|
const reversedLinkRe =
|
||||||
/(^|[^\\])\(([^()]+)\)\[([^\]^][^\]]*)\](?!\()/g;
|
/(^|[^\\])\(([^()]+)\)\[([^\]^][^\]]*)\](?!\()/g;
|
||||||
|
@ -16,13 +17,12 @@ module.exports = {
|
||||||
"tags": [ "links" ],
|
"tags": [ "links" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD011(params, onError) {
|
"function": function MD011(params, onError) {
|
||||||
const { tokens } = params.parsers.micromark;
|
|
||||||
const codeBlockLineNumbers = new Set();
|
const codeBlockLineNumbers = new Set();
|
||||||
for (const codeBlock of filterByTypes(tokens, [ "codeFenced", "codeIndented" ])) {
|
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
||||||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
||||||
}
|
}
|
||||||
const exclusions = [];
|
const exclusions = [];
|
||||||
for (const codeText of filterByTypes(tokens, [ "codeText" ])) {
|
for (const codeText of filterByTypesCached([ "codeText" ])) {
|
||||||
exclusions.push(...getExclusionsForToken(params.lines, codeText));
|
exclusions.push(...getExclusionsForToken(params.lines, codeText));
|
||||||
}
|
}
|
||||||
for (const [ lineIndex, line ] of params.lines.entries()) {
|
for (const [ lineIndex, line ] of params.lines.entries()) {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { addRangeToSet, filterByTypes } = require("../helpers/micromark.cjs");
|
const { addRangeToSet } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -14,9 +15,9 @@ module.exports = {
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD012(params, onError) {
|
"function": function MD012(params, onError) {
|
||||||
const maximum = Number(params.config.maximum || 1);
|
const maximum = Number(params.config.maximum || 1);
|
||||||
const { lines, parsers } = params;
|
const { lines } = params;
|
||||||
const codeBlockLineNumbers = new Set();
|
const codeBlockLineNumbers = new Set();
|
||||||
for (const codeBlock of filterByTypes(parsers.micromark.tokens, [ "codeFenced", "codeIndented" ])) {
|
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
||||||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
||||||
}
|
}
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
18
lib/md013.js
18
lib/md013.js
|
@ -3,8 +3,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { referenceLinkImageData } = require("./cache");
|
const { getReferenceLinkImageData } = require("./cache");
|
||||||
const { addRangeToSet, filterByTypes, getDescendantsByType } = require("../helpers/micromark.cjs");
|
const { addRangeToSet, getDescendantsByType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const longLineRePrefix = "^.{";
|
const longLineRePrefix = "^.{";
|
||||||
const longLineRePostfixRelaxed = "}.*\\s.*$";
|
const longLineRePostfixRelaxed = "}.*\\s.*$";
|
||||||
|
@ -40,25 +41,24 @@ module.exports = {
|
||||||
const includeTables = (tables === undefined) ? true : !!tables;
|
const includeTables = (tables === undefined) ? true : !!tables;
|
||||||
const headings = params.config.headings;
|
const headings = params.config.headings;
|
||||||
const includeHeadings = (headings === undefined) ? true : !!headings;
|
const includeHeadings = (headings === undefined) ? true : !!headings;
|
||||||
const { tokens } = params.parsers.micromark;
|
|
||||||
const headingLineNumbers = new Set();
|
const headingLineNumbers = new Set();
|
||||||
for (const heading of filterByTypes(tokens, [ "atxHeading", "setextHeading" ])) {
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
addRangeToSet(headingLineNumbers, heading.startLine, heading.endLine);
|
addRangeToSet(headingLineNumbers, heading.startLine, heading.endLine);
|
||||||
}
|
}
|
||||||
const codeBlockLineNumbers = new Set();
|
const codeBlockLineNumbers = new Set();
|
||||||
for (const codeBlock of filterByTypes(tokens, [ "codeFenced", "codeIndented" ])) {
|
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
||||||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
||||||
}
|
}
|
||||||
const tableLineNumbers = new Set();
|
const tableLineNumbers = new Set();
|
||||||
for (const table of filterByTypes(tokens, [ "table" ])) {
|
for (const table of filterByTypesCached([ "table" ])) {
|
||||||
addRangeToSet(tableLineNumbers, table.startLine, table.endLine);
|
addRangeToSet(tableLineNumbers, table.startLine, table.endLine);
|
||||||
}
|
}
|
||||||
const linkLineNumbers = new Set();
|
const linkLineNumbers = new Set();
|
||||||
for (const link of filterByTypes(tokens, [ "autolink", "image", "link", "literalAutolink" ])) {
|
for (const link of filterByTypesCached([ "autolink", "image", "link", "literalAutolink" ])) {
|
||||||
addRangeToSet(linkLineNumbers, link.startLine, link.endLine);
|
addRangeToSet(linkLineNumbers, link.startLine, link.endLine);
|
||||||
}
|
}
|
||||||
const paragraphDataLineNumbers = new Set();
|
const paragraphDataLineNumbers = new Set();
|
||||||
for (const paragraph of filterByTypes(tokens, [ "paragraph" ])) {
|
for (const paragraph of filterByTypesCached([ "paragraph" ])) {
|
||||||
for (const data of getDescendantsByType(paragraph, [ "data" ])) {
|
for (const data of getDescendantsByType(paragraph, [ "data" ])) {
|
||||||
addRangeToSet(paragraphDataLineNumbers, data.startLine, data.endLine);
|
addRangeToSet(paragraphDataLineNumbers, data.startLine, data.endLine);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ module.exports = {
|
||||||
linkOnlyLineNumbers.add(lineNumber);
|
linkOnlyLineNumbers.add(lineNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const definitionLineIndices = new Set(referenceLinkImageData().definitionLineIndices);
|
const definitionLineIndices = new Set(getReferenceLinkImageData().definitionLineIndices);
|
||||||
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) {
|
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) {
|
||||||
const line = params.lines[lineIndex];
|
const line = params.lines[lineIndex];
|
||||||
const lineNumber = lineIndex + 1;
|
const lineNumber = lineIndex + 1;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const dollarCommandRe = /^(\s*)(\$\s+)/;
|
const dollarCommandRe = /^(\s*)(\$\s+)/;
|
||||||
|
|
||||||
|
@ -15,11 +16,7 @@ module.exports = {
|
||||||
"tags": [ "code" ],
|
"tags": [ "code" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD014(params, onError) {
|
"function": function MD014(params, onError) {
|
||||||
const codeBlocks = filterByTypes(
|
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "codeFenced", "codeIndented" ]
|
|
||||||
);
|
|
||||||
for (const codeBlock of codeBlocks) {
|
|
||||||
const codeFlowValues = filterByTypes(
|
const codeFlowValues = filterByTypes(
|
||||||
codeBlock.children,
|
codeBlock.children,
|
||||||
[ "codeFlowValue" ]
|
[ "codeFlowValue" ]
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { addRangeToSet, filterByTypes } = require("../helpers/micromark.cjs");
|
const { addRangeToSet } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -13,9 +14,9 @@ module.exports = {
|
||||||
"tags": [ "headings", "atx", "spaces" ],
|
"tags": [ "headings", "atx", "spaces" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD018(params, onError) {
|
"function": function MD018(params, onError) {
|
||||||
const { lines, parsers } = params;
|
const { lines } = params;
|
||||||
const ignoreBlockLineNumbers = new Set();
|
const ignoreBlockLineNumbers = new Set();
|
||||||
for (const ignoreBlock of filterByTypes(parsers.micromark.tokens, [ "codeIndented", "codeFenced", "htmlFlow" ])) {
|
for (const ignoreBlock of filterByTypesCached([ "codeFenced", "codeIndented", "htmlFlow" ])) {
|
||||||
addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine);
|
addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine);
|
||||||
}
|
}
|
||||||
for (const [ lineIndex, line ] of lines.entries()) {
|
for (const [ lineIndex, line ] of lines.entries()) {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers/helpers");
|
const { addErrorContext } = require("../helpers/helpers");
|
||||||
const { filterByTypes, getHeadingStyle } = require("../helpers/micromark.cjs");
|
const { getHeadingStyle } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate heading sequence and whitespace length at start or end.
|
* Validate heading sequence and whitespace length at start or end.
|
||||||
|
@ -55,10 +56,8 @@ module.exports = [
|
||||||
"tags": [ "headings", "atx", "spaces" ],
|
"tags": [ "headings", "atx", "spaces" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD019(params, onError) {
|
"function": function MD019(params, onError) {
|
||||||
const atxHeadings = filterByTypes(
|
const atxHeadings = filterByTypesCached([ "atxHeading" ])
|
||||||
params.parsers.micromark.tokens,
|
.filter((heading) => getHeadingStyle(heading) === "atx");
|
||||||
[ "atxHeading" ]
|
|
||||||
).filter((heading) => getHeadingStyle(heading) === "atx");
|
|
||||||
for (const atxHeading of atxHeadings) {
|
for (const atxHeading of atxHeadings) {
|
||||||
validateHeadingSpaces(onError, atxHeading, 1);
|
validateHeadingSpaces(onError, atxHeading, 1);
|
||||||
}
|
}
|
||||||
|
@ -70,10 +69,8 @@ module.exports = [
|
||||||
"tags": [ "headings", "atx_closed", "spaces" ],
|
"tags": [ "headings", "atx_closed", "spaces" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD021(params, onError) {
|
"function": function MD021(params, onError) {
|
||||||
const atxClosedHeadings = filterByTypes(
|
const atxClosedHeadings = filterByTypesCached([ "atxHeading" ])
|
||||||
params.parsers.micromark.tokens,
|
.filter((heading) => getHeadingStyle(heading) === "atx_closed");
|
||||||
[ "atxHeading" ]
|
|
||||||
).filter((heading) => getHeadingStyle(heading) === "atx_closed");
|
|
||||||
for (const atxClosedHeading of atxClosedHeadings) {
|
for (const atxClosedHeading of atxClosedHeadings) {
|
||||||
validateHeadingSpaces(onError, atxClosedHeading, 1);
|
validateHeadingSpaces(onError, atxClosedHeading, 1);
|
||||||
validateHeadingSpaces(onError, atxClosedHeading, -1);
|
validateHeadingSpaces(onError, atxClosedHeading, -1);
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { addRangeToSet, filterByTypes } = require("../helpers/micromark.cjs");
|
const { addRangeToSet } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -13,9 +14,9 @@ module.exports = {
|
||||||
"tags": [ "headings", "atx_closed", "spaces" ],
|
"tags": [ "headings", "atx_closed", "spaces" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD020(params, onError) {
|
"function": function MD020(params, onError) {
|
||||||
const { lines, parsers } = params;
|
const { lines } = params;
|
||||||
const ignoreBlockLineNumbers = new Set();
|
const ignoreBlockLineNumbers = new Set();
|
||||||
for (const ignoreBlock of filterByTypes(parsers.micromark.tokens, [ "codeIndented", "codeFenced", "htmlFlow" ])) {
|
for (const ignoreBlock of filterByTypesCached([ "codeFenced", "codeIndented", "htmlFlow" ])) {
|
||||||
addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine);
|
addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine);
|
||||||
}
|
}
|
||||||
for (const [ lineIndex, line ] of lines.entries()) {
|
for (const [ lineIndex, line ] of lines.entries()) {
|
||||||
|
|
13
lib/md022.js
13
lib/md022.js
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf, blockquotePrefixRe, isBlankLine } =
|
const { addErrorDetailIf, blockquotePrefixRe, isBlankLine } = require("../helpers");
|
||||||
require("../helpers");
|
const { getHeadingLevel } = require("../helpers/micromark.cjs");
|
||||||
const { filterByTypes, getHeadingLevel } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const defaultLines = 1;
|
const defaultLines = 1;
|
||||||
|
|
||||||
|
@ -41,12 +41,7 @@ module.exports = {
|
||||||
const getLinesAbove = getLinesFunction(params.config.lines_above);
|
const getLinesAbove = getLinesFunction(params.config.lines_above);
|
||||||
const getLinesBelow = getLinesFunction(params.config.lines_below);
|
const getLinesBelow = getLinesFunction(params.config.lines_below);
|
||||||
const { lines } = params;
|
const { lines } = params;
|
||||||
const headings = filterByTypes(
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
|
||||||
const { startLine, endLine } = heading;
|
const { startLine, endLine } = heading;
|
||||||
const line = lines[startLine - 1].trim();
|
const line = lines[startLine - 1].trim();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -13,10 +13,7 @@ module.exports = {
|
||||||
"tags": [ "headings", "spaces" ],
|
"tags": [ "headings", "spaces" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD023(params, onError) {
|
"function": function MD023(params, onError) {
|
||||||
const headings = filterByTypes(
|
const headings = filterByTypesCached([ "atxHeading", "linePrefix", "setextHeading" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "linePrefix", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (let i = 0; i < headings.length - 1; i++) {
|
for (let i = 0; i < headings.length - 1; i++) {
|
||||||
if (
|
if (
|
||||||
(headings[i].type === "linePrefix") &&
|
(headings[i].type === "linePrefix") &&
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes, getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs");
|
const { getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -17,11 +18,7 @@ module.exports = {
|
||||||
const knownContents = [ null, [] ];
|
const knownContents = [ null, [] ];
|
||||||
let lastLevel = 1;
|
let lastLevel = 1;
|
||||||
let knownContent = knownContents[lastLevel];
|
let knownContent = knownContents[lastLevel];
|
||||||
const headings = filterByTypes(
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
|
||||||
const headingText = getHeadingText(heading);
|
const headingText = getHeadingText(heading);
|
||||||
if (siblingsOnly) {
|
if (siblingsOnly) {
|
||||||
const newLevel = getHeadingLevel(heading);
|
const newLevel = getHeadingLevel(heading);
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext, frontMatterHasTitle } = require("../helpers");
|
const { addErrorContext, frontMatterHasTitle } = require("../helpers");
|
||||||
const { filterByTypes, getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs");
|
const { getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -20,11 +21,7 @@ module.exports = {
|
||||||
params.config.front_matter_title
|
params.config.front_matter_title
|
||||||
);
|
);
|
||||||
let hasTopLevelHeading = false;
|
let hasTopLevelHeading = false;
|
||||||
const headings = filterByTypes(
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
|
||||||
const headingLevel = getHeadingLevel(heading);
|
const headingLevel = getHeadingLevel(heading);
|
||||||
if (headingLevel === level) {
|
if (headingLevel === level) {
|
||||||
if (hasTopLevelHeading || foundFrontMatterTitle) {
|
if (hasTopLevelHeading || foundFrontMatterTitle) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
const { addError, allPunctuationNoQuestion, endOfLineGemojiCodeRe,
|
const { addError, allPunctuationNoQuestion, endOfLineGemojiCodeRe,
|
||||||
endOfLineHtmlEntityRe, escapeForRegExp } = require("../helpers");
|
endOfLineHtmlEntityRe, escapeForRegExp } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -20,10 +20,7 @@ module.exports = {
|
||||||
);
|
);
|
||||||
const trailingPunctuationRe =
|
const trailingPunctuationRe =
|
||||||
new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$");
|
new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$");
|
||||||
const headings = filterByTypes(
|
const headings = filterByTypesCached([ "atxHeadingText", "setextHeadingText" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeadingText", "setextHeadingText" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
for (const heading of headings) {
|
||||||
const { endColumn, endLine, text } = heading;
|
const { endColumn, endLine, text } = heading;
|
||||||
const match = trailingPunctuationRe.exec(text);
|
const match = trailingPunctuationRe.exec(text);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -13,9 +13,8 @@ module.exports = {
|
||||||
"tags": ["blockquote", "whitespace", "indentation"],
|
"tags": ["blockquote", "whitespace", "indentation"],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD027(params, onError) {
|
"function": function MD027(params, onError) {
|
||||||
const micromarkTokens = params.parsers.micromark.tokens;
|
for (const token of filterByTypesCached([ "linePrefix" ])) {
|
||||||
for (const token of filterByTypes(micromarkTokens, [ "linePrefix" ])) {
|
const siblings = token.parent?.children || params.parsers.micromark.tokens;
|
||||||
const siblings = token.parent?.children || micromarkTokens;
|
|
||||||
if (siblings[siblings.indexOf(token) - 1]?.type === "blockQuotePrefix") {
|
if (siblings[siblings.indexOf(token) - 1]?.type === "blockQuotePrefix") {
|
||||||
const { startColumn, startLine, text } = token;
|
const { startColumn, startLine, text } = token;
|
||||||
const { length } = text;
|
const { length } = text;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError } = require("../helpers");
|
const { addError } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const ignoreTypes = new Set([ "lineEnding", "listItemIndent", "linePrefix" ]);
|
const ignoreTypes = new Set([ "lineEnding", "listItemIndent", "linePrefix" ]);
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@ module.exports = {
|
||||||
"tags": [ "blockquote", "whitespace" ],
|
"tags": [ "blockquote", "whitespace" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD028(params, onError) {
|
"function": function MD028(params, onError) {
|
||||||
const micromarkTokens = params.parsers.micromark.tokens;
|
for (const token of filterByTypesCached([ "blockQuote" ])) {
|
||||||
for (const token of filterByTypes(micromarkTokens, [ "blockQuote" ])) {
|
|
||||||
const errorLineNumbers = [];
|
const errorLineNumbers = [];
|
||||||
const siblings = token.parent?.children || micromarkTokens;
|
const siblings = token.parent?.children || params.parsers.micromark.tokens;
|
||||||
for (let i = siblings.indexOf(token) + 1; i < siblings.length; i++) {
|
for (let i = siblings.indexOf(token) + 1; i < siblings.length; i++) {
|
||||||
const sibling = siblings[i];
|
const sibling = siblings[i];
|
||||||
const { startLine, type } = sibling;
|
const { startLine, type } = sibling;
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes, getDescendantsByType, getTokenTextByType } = require("../helpers/micromark.cjs");
|
const { getDescendantsByType, getTokenTextByType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const listStyleExamples = {
|
const listStyleExamples = {
|
||||||
"one": "1/1/1",
|
"one": "1/1/1",
|
||||||
|
@ -30,7 +31,7 @@ module.exports = {
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD029(params, onError) {
|
"function": function MD029(params, onError) {
|
||||||
const style = String(params.config.style || "one_or_ordered");
|
const style = String(params.config.style || "one_or_ordered");
|
||||||
for (const listOrdered of filterByTypes(params.parsers.micromark.tokens, [ "listOrdered" ])) {
|
for (const listOrdered of filterByTypesCached([ "listOrdered" ])) {
|
||||||
const listItemPrefixes = getDescendantsByType(listOrdered, [ "listItemPrefix" ]);
|
const listItemPrefixes = getDescendantsByType(listOrdered, [ "listItemPrefix" ]);
|
||||||
let expected = 1;
|
let expected = 1;
|
||||||
let incrementing = false;
|
let incrementing = false;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -17,11 +17,7 @@ module.exports = {
|
||||||
const olSingle = Number(params.config.ol_single || 1);
|
const olSingle = Number(params.config.ol_single || 1);
|
||||||
const ulMulti = Number(params.config.ul_multi || 1);
|
const ulMulti = Number(params.config.ul_multi || 1);
|
||||||
const olMulti = Number(params.config.ol_multi || 1);
|
const olMulti = Number(params.config.ol_multi || 1);
|
||||||
const lists = filterByTypes(
|
for (const list of filterByTypesCached([ "listOrdered", "listUnordered" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "listOrdered", "listUnordered" ]
|
|
||||||
);
|
|
||||||
for (const list of lists) {
|
|
||||||
const ordered = (list.type === "listOrdered");
|
const ordered = (list.type === "listOrdered");
|
||||||
const listItemPrefixes =
|
const listItemPrefixes =
|
||||||
list.children.filter((token) => (token.type === "listItemPrefix"));
|
list.children.filter((token) => (token.type === "listItemPrefix"));
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext, isBlankLine } = require("../helpers");
|
const { addErrorContext, isBlankLine } = require("../helpers");
|
||||||
const { filterByTypes, getTokenParentOfType } = require("../helpers/micromark.cjs");
|
const { getTokenParentOfType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const codeFencePrefixRe = /^(.*?)[`~]/;
|
const codeFencePrefixRe = /^(.*?)[`~]/;
|
||||||
|
|
||||||
|
@ -47,8 +48,8 @@ module.exports = {
|
||||||
"function": function MD031(params, onError) {
|
"function": function MD031(params, onError) {
|
||||||
const listItems = params.config.list_items;
|
const listItems = params.config.list_items;
|
||||||
const includeListItems = (listItems === undefined) ? true : !!listItems;
|
const includeListItems = (listItems === undefined) ? true : !!listItems;
|
||||||
const { lines, parsers } = params;
|
const { lines } = params;
|
||||||
for (const codeBlock of filterByTypes(parsers.micromark.tokens, [ "codeFenced" ])) {
|
for (const codeBlock of filterByTypesCached([ "codeFenced" ])) {
|
||||||
if (includeListItems || !(getTokenParentOfType(codeBlock, [ "listOrdered", "listUnordered" ]))) {
|
if (includeListItems || !(getTokenParentOfType(codeBlock, [ "listOrdered", "listUnordered" ]))) {
|
||||||
if (!isBlankLine(lines[codeBlock.startLine - 2])) {
|
if (!isBlankLine(lines[codeBlock.startLine - 2])) {
|
||||||
addError(onError, lines, codeBlock.startLine, true);
|
addError(onError, lines, codeBlock.startLine, true);
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, nextLinesRe } = require("../helpers");
|
const { addError, nextLinesRe } = require("../helpers");
|
||||||
const { filterByTypes, getHtmlTagInfo } =
|
const { getHtmlTagInfo } = require("../helpers/micromark.cjs");
|
||||||
require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -17,7 +17,7 @@ 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());
|
||||||
for (const token of filterByTypes(params.parsers.micromark.tokens, [ "htmlText" ], true)) {
|
for (const token of filterByTypesCached([ "htmlText" ], true)) {
|
||||||
const htmlTagInfo = getHtmlTagInfo(token);
|
const htmlTagInfo = getHtmlTagInfo(token);
|
||||||
if (
|
if (
|
||||||
htmlTagInfo &&
|
htmlTagInfo &&
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByPredicate, filterByTypes, getHtmlTagInfo, inHtmlFlow, parse } =
|
const { filterByPredicate, getHtmlTagInfo, inHtmlFlow, parse } = require("../helpers/micromark.cjs");
|
||||||
require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -70,10 +70,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const autoLinks = filterByTypes(
|
const autoLinks = filterByTypesCached([ "literalAutolink" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "literalAutolink" ]
|
|
||||||
);
|
|
||||||
if (autoLinks.length > 0) {
|
if (autoLinks.length > 0) {
|
||||||
// Re-parse with correct link/image reference definition handling
|
// Re-parse with correct link/image reference definition handling
|
||||||
const document = params.lines.join("\n");
|
const document = params.lines.join("\n");
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -14,10 +14,7 @@ module.exports = {
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD035(params, onError) {
|
"function": function MD035(params, onError) {
|
||||||
let style = String(params.config.style || "consistent").trim();
|
let style = String(params.config.style || "consistent").trim();
|
||||||
const thematicBreaks = filterByTypes(
|
const thematicBreaks = filterByTypesCached([ "thematicBreak" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "thematicBreak" ]
|
|
||||||
);
|
|
||||||
for (const token of thematicBreaks) {
|
for (const token of thematicBreaks) {
|
||||||
const { startLine, text } = token;
|
const { startLine, text } = token;
|
||||||
if (style === "consistent") {
|
if (style === "consistent") {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext, allPunctuation } = require("../helpers");
|
const { addErrorContext, allPunctuation } = require("../helpers");
|
||||||
const { filterByTypes, matchAndGetTokensByType } = require("../helpers/micromark.cjs");
|
const { matchAndGetTokensByType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
/** @typedef {import("../helpers/micromark.cjs").TokenType} TokenType */
|
/** @typedef {import("../helpers/micromark.cjs").TokenType} TokenType */
|
||||||
/** @type {Map<TokenType, TokenType[]>} */
|
/** @type {Map<TokenType, TokenType[]>} */
|
||||||
|
@ -24,7 +25,7 @@ module.exports = {
|
||||||
punctuation = String((punctuation === undefined) ? allPunctuation : punctuation);
|
punctuation = String((punctuation === undefined) ? allPunctuation : punctuation);
|
||||||
const punctuationRe = new RegExp("[" + punctuation + "]$");
|
const punctuationRe = new RegExp("[" + punctuation + "]$");
|
||||||
const paragraphTokens =
|
const paragraphTokens =
|
||||||
filterByTypes(params.parsers.micromark.tokens, [ "paragraph" ]).
|
filterByTypesCached([ "paragraph" ]).
|
||||||
filter((token) =>
|
filter((token) =>
|
||||||
(token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1)
|
(token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1)
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs");
|
const { tokenIfType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const leftSpaceRe = /^\s(?:[^`]|$)/;
|
const leftSpaceRe = /^\s(?:[^`]|$)/;
|
||||||
const rightSpaceRe = /[^`]\s$/;
|
const rightSpaceRe = /[^`]\s$/;
|
||||||
|
@ -26,10 +27,7 @@ module.exports = {
|
||||||
"tags": [ "whitespace", "code" ],
|
"tags": [ "whitespace", "code" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD038(params, onError) {
|
"function": function MD038(params, onError) {
|
||||||
const codeTexts = filterByTypes(
|
const codeTexts = filterByTypesCached([ "codeText" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "codeText" ]
|
|
||||||
);
|
|
||||||
for (const codeText of codeTexts) {
|
for (const codeText of codeTexts) {
|
||||||
const { children } = codeText;
|
const { children } = codeText;
|
||||||
const first = 0;
|
const first = 0;
|
||||||
|
|
10
lib/md039.js
10
lib/md039.js
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
||||||
const { referenceLinkImageData } = require("./cache");
|
const { getReferenceLinkImageData, filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an error for a label space issue.
|
* Adds an error for a label space issue.
|
||||||
|
@ -56,11 +56,9 @@ module.exports = {
|
||||||
"tags": [ "whitespace", "links" ],
|
"tags": [ "whitespace", "links" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD039(params, onError) {
|
"function": function MD039(params, onError) {
|
||||||
const { definitions } = referenceLinkImageData();
|
const { definitions } = getReferenceLinkImageData();
|
||||||
const labels = filterByTypes(
|
const labels = filterByTypesCached([ "label" ]).
|
||||||
params.parsers.micromark.tokens,
|
filter((label) => label.parent?.type === "link");
|
||||||
[ "label" ]
|
|
||||||
).filter((label) => label.parent?.type === "link");
|
|
||||||
for (const label of labels) {
|
for (const label of labels) {
|
||||||
const labelTexts = filterByTypes(
|
const labelTexts = filterByTypes(
|
||||||
label.children,
|
label.children,
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, addErrorContext } = require("../helpers");
|
const { addError, addErrorContext } = require("../helpers");
|
||||||
const { filterByTypes, getTokenTextByType, tokenIfType } =
|
const { getTokenTextByType, tokenIfType } = require("../helpers/micromark.cjs");
|
||||||
require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -17,10 +17,7 @@ module.exports = {
|
||||||
let allowed = params.config.allowed_languages;
|
let allowed = params.config.allowed_languages;
|
||||||
allowed = Array.isArray(allowed) ? allowed : [];
|
allowed = Array.isArray(allowed) ? allowed : [];
|
||||||
const languageOnly = !!params.config.language_only;
|
const languageOnly = !!params.config.language_only;
|
||||||
const fencedCodes = filterByTypes(
|
const fencedCodes = filterByTypesCached([ "codeFenced" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "codeFenced" ]
|
|
||||||
);
|
|
||||||
for (const fencedCode of fencedCodes) {
|
for (const fencedCode of fencedCodes) {
|
||||||
const openingFence = tokenIfType(fencedCode.children[0], "codeFencedFence");
|
const openingFence = tokenIfType(fencedCode.children[0], "codeFencedFence");
|
||||||
if (openingFence) {
|
if (openingFence) {
|
||||||
|
|
11
lib/md042.js
11
lib/md042.js
|
@ -3,8 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext } = require("../helpers");
|
const { addErrorContext } = require("../helpers");
|
||||||
const { getDescendantsByType, filterByTypes } = require("../helpers/micromark.cjs");
|
const { getDescendantsByType } = require("../helpers/micromark.cjs");
|
||||||
const { referenceLinkImageData } = require("./cache");
|
const { getReferenceLinkImageData, filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -14,15 +14,12 @@ module.exports = {
|
||||||
"tags": [ "links" ],
|
"tags": [ "links" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD042(params, onError) {
|
"function": function MD042(params, onError) {
|
||||||
const { definitions } = referenceLinkImageData();
|
const { definitions } = getReferenceLinkImageData();
|
||||||
const isReferenceDefinitionHash = (token) => {
|
const isReferenceDefinitionHash = (token) => {
|
||||||
const definition = definitions.get(token.text.trim());
|
const definition = definitions.get(token.text.trim());
|
||||||
return (definition && (definition[1] === "#"));
|
return (definition && (definition[1] === "#"));
|
||||||
};
|
};
|
||||||
const links = filterByTypes(
|
const links = filterByTypesCached([ "link" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "link" ]
|
|
||||||
);
|
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
const labelText = getDescendantsByType(link, [ "label", "labelText" ]);
|
const labelText = getDescendantsByType(link, [ "label", "labelText" ]);
|
||||||
const reference = getDescendantsByType(link, [ "reference" ]);
|
const reference = getDescendantsByType(link, [ "reference" ]);
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext, addErrorDetailIf } = require("../helpers");
|
const { addErrorContext, addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes, getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs");
|
const { getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -25,11 +26,7 @@ module.exports = {
|
||||||
let anyHeadings = false;
|
let anyHeadings = false;
|
||||||
const getExpected = () => requiredHeadings[i++] || "[None]";
|
const getExpected = () => requiredHeadings[i++] || "[None]";
|
||||||
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
|
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
|
||||||
const headings = filterByTypes(
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "atxHeading", "setextHeading" ]
|
|
||||||
);
|
|
||||||
for (const heading of headings) {
|
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
const headingText = getHeadingText(heading);
|
const headingText = getHeadingText(heading);
|
||||||
const headingLevel = getHeadingLevel(heading);
|
const headingLevel = getHeadingLevel(heading);
|
||||||
|
|
14
lib/md045.js
14
lib/md045.js
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
const { addError, getHtmlAttributeRe, nextLinesRe } = require("../helpers");
|
const { addError, getHtmlAttributeRe, nextLinesRe } = require("../helpers");
|
||||||
const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
|
const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const altRe = getHtmlAttributeRe("alt");
|
const altRe = getHtmlAttributeRe("alt");
|
||||||
|
|
||||||
|
@ -15,13 +16,8 @@ module.exports = {
|
||||||
"tags": [ "accessibility", "images" ],
|
"tags": [ "accessibility", "images" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD045(params, onError) {
|
"function": function MD045(params, onError) {
|
||||||
const micromarkTokens = params.parsers.micromark.tokens;
|
|
||||||
|
|
||||||
// Process Markdown images
|
// Process Markdown images
|
||||||
const images = filterByTypes(
|
const images = filterByTypesCached([ "image" ]);
|
||||||
micromarkTokens,
|
|
||||||
[ "image" ]
|
|
||||||
);
|
|
||||||
for (const image of images) {
|
for (const image of images) {
|
||||||
const labelTexts = filterByTypes(image.children, [ "labelText" ]);
|
const labelTexts = filterByTypes(image.children, [ "labelText" ]);
|
||||||
if (labelTexts.some((labelText) => labelText.text.length === 0)) {
|
if (labelTexts.some((labelText) => labelText.text.length === 0)) {
|
||||||
|
@ -39,11 +35,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process HTML images
|
// Process HTML images
|
||||||
const htmlTexts = filterByTypes(
|
const htmlTexts = filterByTypesCached([ "htmlText" ], true);
|
||||||
micromarkTokens,
|
|
||||||
[ "htmlText" ],
|
|
||||||
true
|
|
||||||
);
|
|
||||||
for (const htmlText of htmlTexts) {
|
for (const htmlText of htmlTexts) {
|
||||||
const { startColumn, startLine, text } = htmlText;
|
const { startColumn, startLine, text } = htmlText;
|
||||||
const htmlTagInfo = getHtmlTagInfo(htmlText);
|
const htmlTagInfo = getHtmlTagInfo(htmlText);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const tokenTypeToStyle = {
|
const tokenTypeToStyle = {
|
||||||
"codeFenced": "fenced",
|
"codeFenced": "fenced",
|
||||||
|
@ -19,11 +19,7 @@ module.exports = {
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD046(params, onError) {
|
"function": function MD046(params, onError) {
|
||||||
let expectedStyle = String(params.config.style || "consistent");
|
let expectedStyle = String(params.config.style || "consistent");
|
||||||
const codeBlocksAndFences = filterByTypes(
|
for (const token of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "codeFenced", "codeIndented" ]
|
|
||||||
);
|
|
||||||
for (const token of codeBlocksAndFences) {
|
|
||||||
const { startLine, type } = token;
|
const { startLine, type } = token;
|
||||||
if (expectedStyle === "consistent") {
|
if (expectedStyle === "consistent") {
|
||||||
expectedStyle = tokenTypeToStyle[type];
|
expectedStyle = tokenTypeToStyle[type];
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorDetailIf, fencedCodeBlockStyleFor } = require("../helpers");
|
const { addErrorDetailIf, fencedCodeBlockStyleFor } = require("../helpers");
|
||||||
const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs");
|
const { tokenIfType } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -15,10 +16,7 @@ module.exports = {
|
||||||
"function": function MD048(params, onError) {
|
"function": function MD048(params, onError) {
|
||||||
const style = String(params.config.style || "consistent");
|
const style = String(params.config.style || "consistent");
|
||||||
let expectedStyle = style;
|
let expectedStyle = style;
|
||||||
const codeFenceds = filterByTypes(
|
const codeFenceds = filterByTypesCached([ "codeFenced" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "codeFenced" ]
|
|
||||||
);
|
|
||||||
for (const codeFenced of codeFenceds) {
|
for (const codeFenced of codeFenceds) {
|
||||||
const codeFencedFence = tokenIfType(codeFenced.children[0], "codeFencedFence");
|
const codeFencedFence = tokenIfType(codeFenced.children[0], "codeFencedFence");
|
||||||
if (codeFencedFence) {
|
if (codeFencedFence) {
|
||||||
|
|
14
lib/md051.js
14
lib/md051.js
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError, addErrorDetailIf, getHtmlAttributeRe } =
|
const { addError, addErrorDetailIf, getHtmlAttributeRe } = require("../helpers");
|
||||||
require("../helpers");
|
const { filterByPredicate, filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
|
||||||
const { filterByPredicate, filterByTypes, getHtmlTagInfo } =
|
const { filterByTypesCached } = require("./cache");
|
||||||
require("../helpers/micromark.cjs");
|
|
||||||
|
|
||||||
// Regular expression for identifying HTML anchor names
|
// Regular expression for identifying HTML anchor names
|
||||||
const idRe = getHtmlAttributeRe("id");
|
const idRe = getHtmlAttributeRe("id");
|
||||||
|
@ -69,11 +68,10 @@ module.exports = {
|
||||||
"tags": [ "links" ],
|
"tags": [ "links" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD051(params, onError) {
|
"function": function MD051(params, onError) {
|
||||||
const micromarkTokens = params.parsers.micromark.tokens;
|
|
||||||
const fragments = new Map();
|
const fragments = new Map();
|
||||||
|
|
||||||
// Process headings
|
// Process headings
|
||||||
const headingTexts = filterByTypes(micromarkTokens, [ "atxHeadingText", "setextHeadingText" ]);
|
const headingTexts = filterByTypesCached([ "atxHeadingText", "setextHeadingText" ]);
|
||||||
for (const headingText of headingTexts) {
|
for (const headingText of headingTexts) {
|
||||||
const fragment = convertHeadingToHTMLFragment(headingText);
|
const fragment = convertHeadingToHTMLFragment(headingText);
|
||||||
if (fragment !== "#") {
|
if (fragment !== "#") {
|
||||||
|
@ -93,7 +91,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process HTML anchors
|
// Process HTML anchors
|
||||||
for (const token of filterByTypes(micromarkTokens, [ "htmlText" ], true)) {
|
for (const token of filterByTypesCached([ "htmlText" ], true)) {
|
||||||
const htmlTagInfo = getHtmlTagInfo(token);
|
const htmlTagInfo = getHtmlTagInfo(token);
|
||||||
if (htmlTagInfo && !htmlTagInfo.close) {
|
if (htmlTagInfo && !htmlTagInfo.close) {
|
||||||
const anchorMatch = idRe.exec(token.text) ||
|
const anchorMatch = idRe.exec(token.text) ||
|
||||||
|
@ -112,7 +110,7 @@ module.exports = {
|
||||||
[ "definition", "definitionDestinationString" ]
|
[ "definition", "definitionDestinationString" ]
|
||||||
];
|
];
|
||||||
for (const [ parentType, definitionType ] of parentChilds) {
|
for (const [ parentType, definitionType ] of parentChilds) {
|
||||||
const links = filterByTypes(micromarkTokens, [ parentType ]);
|
const links = filterByTypesCached([ parentType ]);
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
const definitions = filterByTypes(link.children, [ definitionType ]);
|
const definitions = filterByTypes(link.children, [ definitionType ]);
|
||||||
for (const definition of definitions) {
|
for (const definition of definitions) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addError } = require("../helpers");
|
const { addError } = require("../helpers");
|
||||||
const { referenceLinkImageData } = require("./cache");
|
const { getReferenceLinkImageData } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -16,7 +16,7 @@ module.exports = {
|
||||||
"function": function MD052(params, onError) {
|
"function": function MD052(params, onError) {
|
||||||
const { config, lines } = params;
|
const { config, lines } = params;
|
||||||
const shortcutSyntax = config.shortcut_syntax || false;
|
const shortcutSyntax = config.shortcut_syntax || false;
|
||||||
const { definitions, references, shortcuts } = referenceLinkImageData();
|
const { definitions, references, shortcuts } = getReferenceLinkImageData();
|
||||||
const entries = shortcutSyntax ?
|
const entries = shortcutSyntax ?
|
||||||
[ ...references.entries(), ...shortcuts.entries() ] :
|
[ ...references.entries(), ...shortcuts.entries() ] :
|
||||||
references.entries();
|
references.entries();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
const { addError, ellipsify, linkReferenceDefinitionRe } =
|
const { addError, ellipsify, linkReferenceDefinitionRe } =
|
||||||
require("../helpers");
|
require("../helpers");
|
||||||
const { referenceLinkImageData } = require("./cache");
|
const { getReferenceLinkImageData } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -17,7 +17,7 @@ module.exports = {
|
||||||
const ignored = new Set(params.config.ignored_definitions || [ "//" ]);
|
const ignored = new Set(params.config.ignored_definitions || [ "//" ]);
|
||||||
const lines = params.lines;
|
const lines = params.lines;
|
||||||
const { references, shortcuts, definitions, duplicateDefinitions } =
|
const { references, shortcuts, definitions, duplicateDefinitions } =
|
||||||
referenceLinkImageData();
|
getReferenceLinkImageData();
|
||||||
const singleLineDefinition = (line) => (
|
const singleLineDefinition = (line) => (
|
||||||
line.replace(linkReferenceDefinitionRe, "").trim().length > 0
|
line.replace(linkReferenceDefinitionRe, "").trim().length > 0
|
||||||
);
|
);
|
||||||
|
|
12
lib/md054.js
12
lib/md054.js
|
@ -3,9 +3,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContext, nextLinesRe } = require("../helpers");
|
const { addErrorContext, nextLinesRe } = require("../helpers");
|
||||||
const { filterByTypes, filterByPredicate, getTokenTextByType } =
|
const { filterByPredicate, getTokenTextByType } = require("../helpers/micromark.cjs");
|
||||||
require("../helpers/micromark.cjs");
|
const { getReferenceLinkImageData, filterByTypesCached } = require("./cache");
|
||||||
const { referenceLinkImageData } = require("./cache");
|
|
||||||
|
|
||||||
const backslashEscapeRe = /\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g;
|
const backslashEscapeRe = /\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g;
|
||||||
const removeBackslashEscapes = (text) => text.replace(backslashEscapeRe, "$1");
|
const removeBackslashEscapes = (text) => text.replace(backslashEscapeRe, "$1");
|
||||||
|
@ -40,11 +39,8 @@ module.exports = {
|
||||||
// Everything allowed, nothing to check
|
// Everything allowed, nothing to check
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { definitions } = referenceLinkImageData();
|
const { definitions } = getReferenceLinkImageData();
|
||||||
const links = filterByTypes(
|
const links = filterByTypesCached([ "autolink", "image", "link" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "autolink", "image", "link" ]
|
|
||||||
);
|
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
let label = null;
|
let label = null;
|
||||||
let destination = null;
|
let destination = null;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
|
const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
|
||||||
const ignoreWhitespace = (tokens) => tokens.filter(
|
const ignoreWhitespace = (tokens) => tokens.filter(
|
||||||
|
@ -27,10 +28,7 @@ module.exports = {
|
||||||
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
|
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
|
||||||
let expectedTrailingPipe =
|
let expectedTrailingPipe =
|
||||||
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
|
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
|
||||||
const tables = filterByTypes(
|
const tables = filterByTypesCached([ "table" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "table" ]
|
|
||||||
);
|
|
||||||
for (const table of tables) {
|
for (const table of tables) {
|
||||||
const rows = filterByTypes(
|
const rows = filterByTypes(
|
||||||
table.children,
|
table.children,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
const { addErrorDetailIf } = require("../helpers");
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
||||||
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
const makeRange = (start, end) => [ start, end - start + 1 ];
|
const makeRange = (start, end) => [ start, end - start + 1 ];
|
||||||
|
|
||||||
|
@ -15,10 +16,7 @@ module.exports = {
|
||||||
"tags": [ "table" ],
|
"tags": [ "table" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD056(params, onError) {
|
"function": function MD056(params, onError) {
|
||||||
const tables = filterByTypes(
|
const tables = filterByTypesCached([ "table" ]);
|
||||||
params.parsers.micromark.tokens,
|
|
||||||
[ "table" ]
|
|
||||||
);
|
|
||||||
for (const table of tables) {
|
for (const table of tables) {
|
||||||
const rows = filterByTypes(
|
const rows = filterByTypes(
|
||||||
table.children,
|
table.children,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { addErrorContextForLine, isBlankLine } = require("../helpers");
|
const { addErrorContextForLine, isBlankLine } = require("../helpers");
|
||||||
const { filterByTypes } = require("../helpers/micromark.cjs");
|
const { filterByTypesCached } = require("./cache");
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/valid-types
|
// eslint-disable-next-line jsdoc/valid-types
|
||||||
/** @type import("./markdownlint").Rule */
|
/** @type import("./markdownlint").Rule */
|
||||||
|
@ -13,12 +13,9 @@ module.exports = {
|
||||||
"tags": [ "table" ],
|
"tags": [ "table" ],
|
||||||
"parser": "micromark",
|
"parser": "micromark",
|
||||||
"function": function MD058(params, onError) {
|
"function": function MD058(params, onError) {
|
||||||
const { lines, parsers } = params;
|
const { lines } = params;
|
||||||
// For every table...
|
// For every table...
|
||||||
const tables = filterByTypes(
|
const tables = filterByTypesCached([ "table" ]);
|
||||||
parsers.micromark.tokens,
|
|
||||||
[ "table" ]
|
|
||||||
);
|
|
||||||
for (const table of tables) {
|
for (const table of tables) {
|
||||||
// Look for a blank line above the table
|
// Look for a blank line above the table
|
||||||
const firstIndex = table.startLine - 1;
|
const firstIndex = table.startLine - 1;
|
||||||
|
|
|
@ -921,8 +921,8 @@ test("getReferenceLinkImageData().shortcuts", (t) => {
|
||||||
"parser": "none",
|
"parser": "none",
|
||||||
"function":
|
"function":
|
||||||
() => {
|
() => {
|
||||||
const { referenceLinkImageData } = require("../lib/cache");
|
const { getReferenceLinkImageData } = require("../lib/cache");
|
||||||
const { shortcuts } = referenceLinkImageData();
|
const { shortcuts } = getReferenceLinkImageData();
|
||||||
t.is(shortcuts.size, 0, [ ...shortcuts.keys() ].join(", "));
|
t.is(shortcuts.size, 0, [ ...shortcuts.keys() ].join(", "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue