mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 14:30:12 +01:00
Make inHtmlFlow more efficient and simplify filterByTypes implementation.
This commit is contained in:
parent
12502f6571
commit
106ca0bc90
2 changed files with 64 additions and 78 deletions
|
|
@ -1240,8 +1240,8 @@ const {
|
||||||
} = __webpack_require__(/*! markdownlint-micromark */ "markdownlint-micromark");
|
} = __webpack_require__(/*! markdownlint-micromark */ "markdownlint-micromark");
|
||||||
const { newLineRe } = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js");
|
const { newLineRe } = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js");
|
||||||
|
|
||||||
const flatTokensWithHtmlFlowSymbol = Symbol("flat-tokens-with-html-flow");
|
const flatTokensSymbol = Symbol("flat-tokens");
|
||||||
const flatTokensWithoutHtmlFlowSymbol = Symbol("flat-tokens-without-html-flow");
|
const reparseSymbol = Symbol("reparse");
|
||||||
|
|
||||||
/** @typedef {import("markdownlint-micromark").Event} Event */
|
/** @typedef {import("markdownlint-micromark").Event} Event */
|
||||||
/** @typedef {import("markdownlint-micromark").ParseOptions} ParseOptions */
|
/** @typedef {import("markdownlint-micromark").ParseOptions} ParseOptions */
|
||||||
|
|
@ -1249,29 +1249,13 @@ const flatTokensWithoutHtmlFlowSymbol = Symbol("flat-tokens-without-html-flow");
|
||||||
/** @typedef {import("../lib/markdownlint.js").MicromarkToken} Token */
|
/** @typedef {import("../lib/markdownlint.js").MicromarkToken} Token */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the nearest parent of the specified type for a Micromark token.
|
* Determines if a Micromark token is within an htmlFlow.
|
||||||
*
|
*
|
||||||
* @param {Token} token Micromark token.
|
* @param {Token} token Micromark token.
|
||||||
* @param {TokenType[]} types Types to allow.
|
* @returns {boolean} True iff the token is within an htmlFlow.
|
||||||
* @returns {Token | null} Parent token.
|
|
||||||
*/
|
|
||||||
function getTokenParentOfType(token, types) {
|
|
||||||
/** @type {Token | null} */
|
|
||||||
let current = token;
|
|
||||||
while ((current = current.parent) && !types.includes(current.type)) {
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if a Micromark token has an htmlFlow-type parent.
|
|
||||||
*
|
|
||||||
* @param {Token} token Micromark token.
|
|
||||||
* @returns {boolean} True iff the token has an htmlFlow-type parent.
|
|
||||||
*/
|
*/
|
||||||
function inHtmlFlow(token) {
|
function inHtmlFlow(token) {
|
||||||
return getTokenParentOfType(token, [ "htmlFlow" ]) !== null;
|
return token[reparseSymbol];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1364,8 +1348,7 @@ function micromarkParseWithOffset(
|
||||||
|
|
||||||
// Create Token objects
|
// Create Token objects
|
||||||
const document = [];
|
const document = [];
|
||||||
let flatTokensWithHtmlFlow = [];
|
let flatTokens = [];
|
||||||
const flatTokensWithoutHtmlFlow = [];
|
|
||||||
/** @type {Token} */
|
/** @type {Token} */
|
||||||
const root = {
|
const root = {
|
||||||
"type": "data",
|
"type": "data",
|
||||||
|
|
@ -1403,9 +1386,11 @@ function micromarkParseWithOffset(
|
||||||
"children": [],
|
"children": [],
|
||||||
"parent": ((previous === root) ? (ancestor || null) : previous)
|
"parent": ((previous === root) ? (ancestor || null) : previous)
|
||||||
};
|
};
|
||||||
|
if (ancestor) {
|
||||||
|
Object.defineProperty(current, reparseSymbol, { "value": true });
|
||||||
|
}
|
||||||
previous.children.push(current);
|
previous.children.push(current);
|
||||||
flatTokensWithHtmlFlow.push(current);
|
flatTokens.push(current);
|
||||||
flatTokensWithoutHtmlFlow.push(current);
|
|
||||||
if ((current.type === "htmlFlow") && !isHtmlFlowComment(current)) {
|
if ((current.type === "htmlFlow") && !isHtmlFlowComment(current)) {
|
||||||
skipHtmlFlowChildren = true;
|
skipHtmlFlowChildren = true;
|
||||||
if (!reparseOptions || !lines) {
|
if (!reparseOptions || !lines) {
|
||||||
|
|
@ -1434,7 +1419,7 @@ function micromarkParseWithOffset(
|
||||||
current.children = tokens;
|
current.children = tokens;
|
||||||
// Avoid stack overflow of Array.push(...spread)
|
// Avoid stack overflow of Array.push(...spread)
|
||||||
// eslint-disable-next-line unicorn/prefer-spread
|
// eslint-disable-next-line unicorn/prefer-spread
|
||||||
flatTokensWithHtmlFlow = flatTokensWithHtmlFlow.concat(tokens[flatTokensWithHtmlFlowSymbol]);
|
flatTokens = flatTokens.concat(tokens[flatTokensSymbol]);
|
||||||
}
|
}
|
||||||
} else if (kind === "exit") {
|
} else if (kind === "exit") {
|
||||||
if (type === "htmlFlow") {
|
if (type === "htmlFlow") {
|
||||||
|
|
@ -1450,8 +1435,7 @@ function micromarkParseWithOffset(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return document
|
// Return document
|
||||||
Object.defineProperty(document, flatTokensWithHtmlFlowSymbol, { "value": flatTokensWithHtmlFlow });
|
Object.defineProperty(document, flatTokensSymbol, { "value": flatTokens });
|
||||||
Object.defineProperty(document, flatTokensWithoutHtmlFlowSymbol, { "value": flatTokensWithoutHtmlFlow });
|
|
||||||
Object.freeze(document);
|
Object.freeze(document);
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
@ -1541,20 +1525,13 @@ function filterByPredicate(tokens, allowed, transformChildren) {
|
||||||
* @returns {Token[]} Filtered tokens.
|
* @returns {Token[]} Filtered tokens.
|
||||||
*/
|
*/
|
||||||
function filterByTypes(tokens, types, htmlFlow) {
|
function filterByTypes(tokens, types, htmlFlow) {
|
||||||
const predicate = (token) => types.includes(token.type);
|
const predicate = (token) =>
|
||||||
const flatTokens = tokens[
|
(htmlFlow || !inHtmlFlow(token)) && types.includes(token.type);
|
||||||
htmlFlow ?
|
const flatTokens = tokens[flatTokensSymbol];
|
||||||
flatTokensWithHtmlFlowSymbol :
|
|
||||||
flatTokensWithoutHtmlFlowSymbol
|
|
||||||
];
|
|
||||||
if (flatTokens) {
|
if (flatTokens) {
|
||||||
return flatTokens.filter(predicate);
|
return flatTokens.filter(predicate);
|
||||||
}
|
}
|
||||||
const result = filterByPredicate(tokens, predicate);
|
return filterByPredicate(tokens, predicate);
|
||||||
if (htmlFlow) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result.filter((token) => !inHtmlFlow(token));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1628,6 +1605,22 @@ function getHtmlTagInfo(token) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the nearest parent of the specified type for a Micromark token.
|
||||||
|
*
|
||||||
|
* @param {Token} token Micromark token.
|
||||||
|
* @param {TokenType[]} types Types to allow.
|
||||||
|
* @returns {Token | null} Parent token.
|
||||||
|
*/
|
||||||
|
function getTokenParentOfType(token, types) {
|
||||||
|
/** @type {Token | null} */
|
||||||
|
let current = token;
|
||||||
|
while ((current = current.parent) && !types.includes(current.type)) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the text of the first match from a list of Micromark tokens by type.
|
* Get the text of the first match from a list of Micromark tokens by type.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ const {
|
||||||
} = require("markdownlint-micromark");
|
} = require("markdownlint-micromark");
|
||||||
const { newLineRe } = require("./shared.js");
|
const { newLineRe } = require("./shared.js");
|
||||||
|
|
||||||
const flatTokensWithHtmlFlowSymbol = Symbol("flat-tokens-with-html-flow");
|
const flatTokensSymbol = Symbol("flat-tokens");
|
||||||
const flatTokensWithoutHtmlFlowSymbol = Symbol("flat-tokens-without-html-flow");
|
const reparseSymbol = Symbol("reparse");
|
||||||
|
|
||||||
/** @typedef {import("markdownlint-micromark").Event} Event */
|
/** @typedef {import("markdownlint-micromark").Event} Event */
|
||||||
/** @typedef {import("markdownlint-micromark").ParseOptions} ParseOptions */
|
/** @typedef {import("markdownlint-micromark").ParseOptions} ParseOptions */
|
||||||
|
|
@ -19,29 +19,13 @@ const flatTokensWithoutHtmlFlowSymbol = Symbol("flat-tokens-without-html-flow");
|
||||||
/** @typedef {import("../lib/markdownlint.js").MicromarkToken} Token */
|
/** @typedef {import("../lib/markdownlint.js").MicromarkToken} Token */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the nearest parent of the specified type for a Micromark token.
|
* Determines if a Micromark token is within an htmlFlow.
|
||||||
*
|
*
|
||||||
* @param {Token} token Micromark token.
|
* @param {Token} token Micromark token.
|
||||||
* @param {TokenType[]} types Types to allow.
|
* @returns {boolean} True iff the token is within an htmlFlow.
|
||||||
* @returns {Token | null} Parent token.
|
|
||||||
*/
|
|
||||||
function getTokenParentOfType(token, types) {
|
|
||||||
/** @type {Token | null} */
|
|
||||||
let current = token;
|
|
||||||
while ((current = current.parent) && !types.includes(current.type)) {
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if a Micromark token has an htmlFlow-type parent.
|
|
||||||
*
|
|
||||||
* @param {Token} token Micromark token.
|
|
||||||
* @returns {boolean} True iff the token has an htmlFlow-type parent.
|
|
||||||
*/
|
*/
|
||||||
function inHtmlFlow(token) {
|
function inHtmlFlow(token) {
|
||||||
return getTokenParentOfType(token, [ "htmlFlow" ]) !== null;
|
return token[reparseSymbol];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -134,8 +118,7 @@ function micromarkParseWithOffset(
|
||||||
|
|
||||||
// Create Token objects
|
// Create Token objects
|
||||||
const document = [];
|
const document = [];
|
||||||
let flatTokensWithHtmlFlow = [];
|
let flatTokens = [];
|
||||||
const flatTokensWithoutHtmlFlow = [];
|
|
||||||
/** @type {Token} */
|
/** @type {Token} */
|
||||||
const root = {
|
const root = {
|
||||||
"type": "data",
|
"type": "data",
|
||||||
|
|
@ -173,9 +156,11 @@ function micromarkParseWithOffset(
|
||||||
"children": [],
|
"children": [],
|
||||||
"parent": ((previous === root) ? (ancestor || null) : previous)
|
"parent": ((previous === root) ? (ancestor || null) : previous)
|
||||||
};
|
};
|
||||||
|
if (ancestor) {
|
||||||
|
Object.defineProperty(current, reparseSymbol, { "value": true });
|
||||||
|
}
|
||||||
previous.children.push(current);
|
previous.children.push(current);
|
||||||
flatTokensWithHtmlFlow.push(current);
|
flatTokens.push(current);
|
||||||
flatTokensWithoutHtmlFlow.push(current);
|
|
||||||
if ((current.type === "htmlFlow") && !isHtmlFlowComment(current)) {
|
if ((current.type === "htmlFlow") && !isHtmlFlowComment(current)) {
|
||||||
skipHtmlFlowChildren = true;
|
skipHtmlFlowChildren = true;
|
||||||
if (!reparseOptions || !lines) {
|
if (!reparseOptions || !lines) {
|
||||||
|
|
@ -204,7 +189,7 @@ function micromarkParseWithOffset(
|
||||||
current.children = tokens;
|
current.children = tokens;
|
||||||
// Avoid stack overflow of Array.push(...spread)
|
// Avoid stack overflow of Array.push(...spread)
|
||||||
// eslint-disable-next-line unicorn/prefer-spread
|
// eslint-disable-next-line unicorn/prefer-spread
|
||||||
flatTokensWithHtmlFlow = flatTokensWithHtmlFlow.concat(tokens[flatTokensWithHtmlFlowSymbol]);
|
flatTokens = flatTokens.concat(tokens[flatTokensSymbol]);
|
||||||
}
|
}
|
||||||
} else if (kind === "exit") {
|
} else if (kind === "exit") {
|
||||||
if (type === "htmlFlow") {
|
if (type === "htmlFlow") {
|
||||||
|
|
@ -220,8 +205,7 @@ function micromarkParseWithOffset(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return document
|
// Return document
|
||||||
Object.defineProperty(document, flatTokensWithHtmlFlowSymbol, { "value": flatTokensWithHtmlFlow });
|
Object.defineProperty(document, flatTokensSymbol, { "value": flatTokens });
|
||||||
Object.defineProperty(document, flatTokensWithoutHtmlFlowSymbol, { "value": flatTokensWithoutHtmlFlow });
|
|
||||||
Object.freeze(document);
|
Object.freeze(document);
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
@ -311,20 +295,13 @@ function filterByPredicate(tokens, allowed, transformChildren) {
|
||||||
* @returns {Token[]} Filtered tokens.
|
* @returns {Token[]} Filtered tokens.
|
||||||
*/
|
*/
|
||||||
function filterByTypes(tokens, types, htmlFlow) {
|
function filterByTypes(tokens, types, htmlFlow) {
|
||||||
const predicate = (token) => types.includes(token.type);
|
const predicate = (token) =>
|
||||||
const flatTokens = tokens[
|
(htmlFlow || !inHtmlFlow(token)) && types.includes(token.type);
|
||||||
htmlFlow ?
|
const flatTokens = tokens[flatTokensSymbol];
|
||||||
flatTokensWithHtmlFlowSymbol :
|
|
||||||
flatTokensWithoutHtmlFlowSymbol
|
|
||||||
];
|
|
||||||
if (flatTokens) {
|
if (flatTokens) {
|
||||||
return flatTokens.filter(predicate);
|
return flatTokens.filter(predicate);
|
||||||
}
|
}
|
||||||
const result = filterByPredicate(tokens, predicate);
|
return filterByPredicate(tokens, predicate);
|
||||||
if (htmlFlow) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result.filter((token) => !inHtmlFlow(token));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -398,6 +375,22 @@ function getHtmlTagInfo(token) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the nearest parent of the specified type for a Micromark token.
|
||||||
|
*
|
||||||
|
* @param {Token} token Micromark token.
|
||||||
|
* @param {TokenType[]} types Types to allow.
|
||||||
|
* @returns {Token | null} Parent token.
|
||||||
|
*/
|
||||||
|
function getTokenParentOfType(token, types) {
|
||||||
|
/** @type {Token | null} */
|
||||||
|
let current = token;
|
||||||
|
while ((current = current.parent) && !types.includes(current.type)) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the text of the first match from a list of Micromark tokens by type.
|
* Get the text of the first match from a list of Micromark tokens by type.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue