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