mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-21 21:30:47 +02:00
Stop running the markdown-it parser unless a custom rule that requires it is present (~7% runtime reduction).
This commit is contained in:
parent
697780b3b6
commit
ea8d596a9b
5 changed files with 102 additions and 36 deletions
|
@ -563,7 +563,7 @@ is allowed to continue and report any violations that were found.
|
|||
|
||||
Type: `Array` of `Array` of `Function` and plugin parameters
|
||||
|
||||
Specifies additional [markdown-it plugins][markdown-it-plugin] to use when
|
||||
Specifies additional [`markdown-it` plugins][markdown-it-plugin] to use when
|
||||
parsing input. Plugins can be used to support additional syntax and features for
|
||||
advanced scenarios.
|
||||
|
||||
|
@ -575,6 +575,13 @@ Each item in the top-level `Array` should be of the form:
|
|||
[ require("markdown-it-plugin"), plugin_param_0, plugin_param_1, ... ]
|
||||
```
|
||||
|
||||
> Note that `markdown-it` plugins are only called when the `markdown-it` parser
|
||||
> is invoked. None of the built-in rules use the `markdown-it` parser, so
|
||||
> `markdown-it` plugins will only be invoked when one or more
|
||||
> [custom rules][custom-rules] that use the `markdown-it` parser are present.
|
||||
|
||||
[custom-rules]: #custom-rules
|
||||
|
||||
##### options.noInlineConfig
|
||||
|
||||
Type: `Boolean`
|
||||
|
|
|
@ -1557,7 +1557,6 @@ module.exports.version = "0.34.0";
|
|||
|
||||
const path = __webpack_require__(/*! node:path */ "?9a52");
|
||||
const { promisify } = __webpack_require__(/*! node:util */ "?39e5");
|
||||
const markdownit = __webpack_require__(/*! markdown-it */ "markdown-it");
|
||||
const micromark = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
||||
// const { deprecatedRuleNames } = require("./constants");
|
||||
const rules = __webpack_require__(/*! ./rules */ "../lib/rules.js");
|
||||
|
@ -1779,13 +1778,17 @@ function freezeToken(token) {
|
|||
/**
|
||||
* Annotate tokens with line/lineNumber and freeze them.
|
||||
*
|
||||
* @param {MarkdownItToken[]} tokens Array of markdown-it tokens.
|
||||
* @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens.
|
||||
* @param {string[]} lines Lines of Markdown content.
|
||||
* @returns {void}
|
||||
*/
|
||||
function annotateAndFreezeTokens(tokens, lines) {
|
||||
let trMap = null;
|
||||
for (const token of tokens) {
|
||||
// eslint-disable-next-line jsdoc/valid-types
|
||||
/** @type MarkdownItToken[] */
|
||||
// @ts-ignore
|
||||
const markdownItTokens = tokens;
|
||||
for (const token of markdownItTokens) {
|
||||
// Provide missing maps for table content
|
||||
if (token.type === "tr_open") {
|
||||
trMap = token.map;
|
||||
|
@ -2075,7 +2078,7 @@ function getEnabledRulesPerLineNumber(
|
|||
* names.
|
||||
* @param {string} name Identifier for the content.
|
||||
* @param {string} content Markdown content.
|
||||
* @param {Object} md Instance of markdown-it.
|
||||
* @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it.
|
||||
* @param {Configuration} config Configuration object.
|
||||
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
||||
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
||||
|
@ -2090,7 +2093,7 @@ function lintContent(
|
|||
aliasToRuleNames,
|
||||
name,
|
||||
content,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -2115,8 +2118,11 @@ function lintContent(
|
|||
configParsers,
|
||||
aliasToRuleNames
|
||||
);
|
||||
const needMarkdownItTokens = ruleList.some(
|
||||
(rule) => (rule.parser === "markdownit") || (rule.parser === undefined)
|
||||
);
|
||||
// Parse content into parser tokens
|
||||
const markdownitTokens = md.parse(content, {});
|
||||
const markdownitTokens = needMarkdownItTokens ? getMarkdownIt().parse(content, {}) : [];
|
||||
const micromarkTokens = micromark.parse(content);
|
||||
// Hide the content of HTML comments from rules
|
||||
content = helpers.clearHtmlCommentText(content);
|
||||
|
@ -2376,7 +2382,7 @@ function lintContent(
|
|||
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
||||
* names.
|
||||
* @param {string} file Path of file to lint.
|
||||
* @param {Object} md Instance of markdown-it.
|
||||
* @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it.
|
||||
* @param {Configuration} config Configuration object.
|
||||
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
||||
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
||||
|
@ -2392,7 +2398,7 @@ function lintFile(
|
|||
ruleList,
|
||||
aliasToRuleNames,
|
||||
file,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -2412,7 +2418,7 @@ function lintFile(
|
|||
aliasToRuleNames,
|
||||
file,
|
||||
content,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -2477,12 +2483,16 @@ function lintInput(options, synchronous, callback) {
|
|||
const noInlineConfig = !!options.noInlineConfig;
|
||||
const resultVersion = (options.resultVersion === undefined) ?
|
||||
3 : options.resultVersion;
|
||||
const md = markdownit({ "html": true });
|
||||
const markdownItPlugins = options.markdownItPlugins || [];
|
||||
for (const plugin of markdownItPlugins) {
|
||||
// @ts-ignore
|
||||
md.use(...plugin);
|
||||
}
|
||||
const getMarkdownIt = () => {
|
||||
const markdownit = __webpack_require__(/*! markdown-it */ "markdown-it");
|
||||
const md = markdownit({ "html": true });
|
||||
const markdownItPlugins = options.markdownItPlugins || [];
|
||||
for (const plugin of markdownItPlugins) {
|
||||
// @ts-ignore
|
||||
md.use(...plugin);
|
||||
}
|
||||
return md;
|
||||
};
|
||||
const fs = options.fs || __webpack_require__(/*! node:fs */ "?d0ee");
|
||||
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
||||
const results = newResults(ruleList);
|
||||
|
@ -2514,7 +2524,7 @@ function lintInput(options, synchronous, callback) {
|
|||
ruleList,
|
||||
aliasToRuleNames,
|
||||
currentItem,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -2533,7 +2543,7 @@ function lintInput(options, synchronous, callback) {
|
|||
aliasToRuleNames,
|
||||
currentItem,
|
||||
strings[currentItem] || "",
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -2848,6 +2858,13 @@ module.exports = markdownlint;
|
|||
|
||||
// Type declarations
|
||||
|
||||
/**
|
||||
* Function to get an instance of the markdown-it parser.
|
||||
*
|
||||
* @callback GetMarkdownIt
|
||||
* @returns {import("markdown-it")}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to implement rule logic.
|
||||
*
|
||||
|
|
6
lib/markdownlint.d.ts
vendored
6
lib/markdownlint.d.ts
vendored
|
@ -8,7 +8,7 @@ export = markdownlint;
|
|||
*/
|
||||
declare function markdownlint(options: Options | null, callback: LintCallback): void;
|
||||
declare namespace markdownlint {
|
||||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
|
||||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, GetMarkdownIt, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
|
||||
}
|
||||
/**
|
||||
* Lint specified Markdown files synchronously.
|
||||
|
@ -49,6 +49,10 @@ declare namespace promises {
|
|||
export { extendConfigPromise as extendConfig };
|
||||
export { readConfigPromise as readConfig };
|
||||
}
|
||||
/**
|
||||
* Function to get an instance of the markdown-it parser.
|
||||
*/
|
||||
type GetMarkdownIt = () => any;
|
||||
/**
|
||||
* Function to implement rule logic.
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
const path = require("node:path");
|
||||
const { promisify } = require("node:util");
|
||||
const markdownit = require("markdown-it");
|
||||
const micromark = require("../helpers/micromark.cjs");
|
||||
// const { deprecatedRuleNames } = require("./constants");
|
||||
const rules = require("./rules");
|
||||
|
@ -226,13 +225,17 @@ function freezeToken(token) {
|
|||
/**
|
||||
* Annotate tokens with line/lineNumber and freeze them.
|
||||
*
|
||||
* @param {MarkdownItToken[]} tokens Array of markdown-it tokens.
|
||||
* @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens.
|
||||
* @param {string[]} lines Lines of Markdown content.
|
||||
* @returns {void}
|
||||
*/
|
||||
function annotateAndFreezeTokens(tokens, lines) {
|
||||
let trMap = null;
|
||||
for (const token of tokens) {
|
||||
// eslint-disable-next-line jsdoc/valid-types
|
||||
/** @type MarkdownItToken[] */
|
||||
// @ts-ignore
|
||||
const markdownItTokens = tokens;
|
||||
for (const token of markdownItTokens) {
|
||||
// Provide missing maps for table content
|
||||
if (token.type === "tr_open") {
|
||||
trMap = token.map;
|
||||
|
@ -522,7 +525,7 @@ function getEnabledRulesPerLineNumber(
|
|||
* names.
|
||||
* @param {string} name Identifier for the content.
|
||||
* @param {string} content Markdown content.
|
||||
* @param {Object} md Instance of markdown-it.
|
||||
* @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it.
|
||||
* @param {Configuration} config Configuration object.
|
||||
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
||||
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
||||
|
@ -537,7 +540,7 @@ function lintContent(
|
|||
aliasToRuleNames,
|
||||
name,
|
||||
content,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -562,8 +565,11 @@ function lintContent(
|
|||
configParsers,
|
||||
aliasToRuleNames
|
||||
);
|
||||
const needMarkdownItTokens = ruleList.some(
|
||||
(rule) => (rule.parser === "markdownit") || (rule.parser === undefined)
|
||||
);
|
||||
// Parse content into parser tokens
|
||||
const markdownitTokens = md.parse(content, {});
|
||||
const markdownitTokens = needMarkdownItTokens ? getMarkdownIt().parse(content, {}) : [];
|
||||
const micromarkTokens = micromark.parse(content);
|
||||
// Hide the content of HTML comments from rules
|
||||
content = helpers.clearHtmlCommentText(content);
|
||||
|
@ -823,7 +829,7 @@ function lintContent(
|
|||
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
||||
* names.
|
||||
* @param {string} file Path of file to lint.
|
||||
* @param {Object} md Instance of markdown-it.
|
||||
* @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it.
|
||||
* @param {Configuration} config Configuration object.
|
||||
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
||||
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
||||
|
@ -839,7 +845,7 @@ function lintFile(
|
|||
ruleList,
|
||||
aliasToRuleNames,
|
||||
file,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -859,7 +865,7 @@ function lintFile(
|
|||
aliasToRuleNames,
|
||||
file,
|
||||
content,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -924,12 +930,16 @@ function lintInput(options, synchronous, callback) {
|
|||
const noInlineConfig = !!options.noInlineConfig;
|
||||
const resultVersion = (options.resultVersion === undefined) ?
|
||||
3 : options.resultVersion;
|
||||
const md = markdownit({ "html": true });
|
||||
const markdownItPlugins = options.markdownItPlugins || [];
|
||||
for (const plugin of markdownItPlugins) {
|
||||
// @ts-ignore
|
||||
md.use(...plugin);
|
||||
}
|
||||
const getMarkdownIt = () => {
|
||||
const markdownit = require("markdown-it");
|
||||
const md = markdownit({ "html": true });
|
||||
const markdownItPlugins = options.markdownItPlugins || [];
|
||||
for (const plugin of markdownItPlugins) {
|
||||
// @ts-ignore
|
||||
md.use(...plugin);
|
||||
}
|
||||
return md;
|
||||
};
|
||||
const fs = options.fs || require("node:fs");
|
||||
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
||||
const results = newResults(ruleList);
|
||||
|
@ -961,7 +971,7 @@ function lintInput(options, synchronous, callback) {
|
|||
ruleList,
|
||||
aliasToRuleNames,
|
||||
currentItem,
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -980,7 +990,7 @@ function lintInput(options, synchronous, callback) {
|
|||
aliasToRuleNames,
|
||||
currentItem,
|
||||
strings[currentItem] || "",
|
||||
md,
|
||||
getMarkdownIt,
|
||||
config,
|
||||
configParsers,
|
||||
frontMatter,
|
||||
|
@ -1295,6 +1305,13 @@ module.exports = markdownlint;
|
|||
|
||||
// Type declarations
|
||||
|
||||
/**
|
||||
* Function to get an instance of the markdown-it parser.
|
||||
*
|
||||
* @callback GetMarkdownIt
|
||||
* @returns {import("markdown-it")}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to implement rule logic.
|
||||
*
|
||||
|
|
|
@ -1109,6 +1109,8 @@ test("markdownItPluginsSingle", (t) => new Promise((resolve) => {
|
|||
"strings": {
|
||||
"string": "# Heading\n\nText\n"
|
||||
},
|
||||
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
||||
"customRules": customRules.anyBlockquote,
|
||||
"markdownItPlugins": [
|
||||
[ pluginInline, "check_text_plugin", "text", () => t.true(true) ]
|
||||
]
|
||||
|
@ -1126,6 +1128,8 @@ test("markdownItPluginsMultiple", (t) => new Promise((resolve) => {
|
|||
"strings": {
|
||||
"string": "# Heading\n\nText H~2~0 text 29^th^ text\n"
|
||||
},
|
||||
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
||||
"customRules": customRules.anyBlockquote,
|
||||
"markdownItPlugins": [
|
||||
[ pluginSub ],
|
||||
[ pluginSup ],
|
||||
|
@ -1140,6 +1144,23 @@ test("markdownItPluginsMultiple", (t) => new Promise((resolve) => {
|
|||
});
|
||||
}));
|
||||
|
||||
test("markdownItPluginsNoMarkdownIt", (t) => new Promise((resolve) => {
|
||||
t.plan(2);
|
||||
markdownlint({
|
||||
"strings": {
|
||||
"string": "# Heading\n\nText\n"
|
||||
},
|
||||
"markdownItPlugins": [
|
||||
[ pluginInline, "check_text_plugin", "text", () => t.fail() ]
|
||||
]
|
||||
}, function callback(err, actual) {
|
||||
t.falsy(err);
|
||||
const expected = { "string": [] };
|
||||
t.deepEqual(actual, expected, "Unexpected issues.");
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
|
||||
test("Pandoc footnote", (t) => new Promise((resolve) => {
|
||||
t.plan(2);
|
||||
markdownlint({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue