mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Introduce options.markdownItFactory (and remove options.markdownItPlugins) so the markdown-it parser can be removed as a direct dependency because it is no longer used by default.
This commit is contained in:
parent
3cbe1cb6c5
commit
d4b981bcb3
11 changed files with 172 additions and 67 deletions
|
@ -14,8 +14,8 @@ Match the coding style of the files you edit. Although everyone has their own
|
||||||
preferences and opinions, a pull request is not the right forum to debate them.
|
preferences and opinions, a pull request is not the right forum to debate them.
|
||||||
|
|
||||||
Do not add new [`dependencies` to `package.json`][dependencies]. The Markdown
|
Do not add new [`dependencies` to `package.json`][dependencies]. The Markdown
|
||||||
parsers [`markdown-it`][markdown-it] and [`micromark`][micromark] are the
|
parser [`micromark`][micromark] (and its extensions) is this project's only
|
||||||
project's only dependencies.
|
dependency.
|
||||||
|
|
||||||
Package versions for `dependencies` and `devDependencies` should be specified
|
Package versions for `dependencies` and `devDependencies` should be specified
|
||||||
exactly (also known as "pinning"). The short explanation is that doing otherwise
|
exactly (also known as "pinning"). The short explanation is that doing otherwise
|
||||||
|
|
33
README.md
33
README.md
|
@ -24,7 +24,7 @@ for Markdown files. It was inspired by - and heavily influenced by - Mark
|
||||||
Harrison's [markdownlint][markdownlint-ruby] for Ruby. The initial rules, rule
|
Harrison's [markdownlint][markdownlint-ruby] for Ruby. The initial rules, rule
|
||||||
documentation, and test cases came from that project.
|
documentation, and test cases came from that project.
|
||||||
|
|
||||||
`markdownlint` uses the [`micromark`][micromark] parser and honors the
|
`markdownlint` uses the [`micromark` parser][micromark] and honors the
|
||||||
[CommonMark][commonmark] specification for Markdown. It additionally supports
|
[CommonMark][commonmark] specification for Markdown. It additionally supports
|
||||||
popular [GitHub Flavored Markdown (GFM)][gfm] syntax like autolinks and tables
|
popular [GitHub Flavored Markdown (GFM)][gfm] syntax like autolinks and tables
|
||||||
as well as directives, footnotes, and math syntax - all implemented by
|
as well as directives, footnotes, and math syntax - all implemented by
|
||||||
|
@ -567,28 +567,35 @@ This setting can be useful in the presence of (custom) rules that encounter
|
||||||
unexpected syntax and fail. By enabling this option, the linting process
|
unexpected syntax and fail. By enabling this option, the linting process
|
||||||
is allowed to continue and report any violations that were found.
|
is allowed to continue and report any violations that were found.
|
||||||
|
|
||||||
##### options.markdownItPlugins
|
##### options.markdownItFactory
|
||||||
|
|
||||||
Type: `Array` of `Array` of `Function` and plugin parameters
|
Type: `Function` returning an instance of a [`markdown-it` parser][markdown-it]
|
||||||
|
|
||||||
Specifies additional [`markdown-it` plugins][markdown-it-plugin] to use when
|
Provides a factory function for creating instances of the `markdown-it` parser.
|
||||||
parsing input. Plugins can be used to support additional syntax and features for
|
|
||||||
advanced scenarios. *Deprecated.*
|
|
||||||
|
|
||||||
[markdown-it-plugin]: https://www.npmjs.com/search?q=keywords:markdown-it-plugin
|
Previous versions of the `markdownlint` library declared `markdown-it` as a
|
||||||
|
direct dependency. This function makes it possible to avoid that dependency
|
||||||
|
entirely. In cases where `markdown-it` is needed, the caller is responsible for
|
||||||
|
declaring the dependency and returning an instance from this factory. If any
|
||||||
|
[`markdown-it` plugins][markdown-it-plugin] are needed, they should be `use`d by
|
||||||
|
the caller before returning the `markdown-it` instance.
|
||||||
|
|
||||||
Each item in the top-level `Array` should be of the form:
|
For compatibility with previous versions of `markdownlint`, this function can be
|
||||||
|
implemented like:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
[ require("markdown-it-plugin"), plugin_param_0, plugin_param_1, ... ]
|
import markdownIt from "markdown-it";
|
||||||
|
const markdownItFactory = () => markdownIt({ "html": true });
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note that `markdown-it` plugins are only called when the `markdown-it` parser
|
> Note that this function is only invoked when a `markdown-it` parser is
|
||||||
> is invoked. None of the built-in rules use the `markdown-it` parser, so
|
> needed. None of the built-in rules use the `markdown-it` parser, so it is only
|
||||||
> `markdown-it` plugins will only be invoked when one or more
|
> invoked when one or more [custom rules][custom-rules] are present that use the
|
||||||
> [custom rules][custom-rules] that use the `markdown-it` parser are present.
|
> `markdown-it` parser.
|
||||||
|
|
||||||
[custom-rules]: #custom-rules
|
[custom-rules]: #custom-rules
|
||||||
|
[markdown-it]: https://github.com/markdown-it/markdown-it
|
||||||
|
[markdown-it-plugin]: https://www.npmjs.com/search?q=keywords:markdown-it-plugin
|
||||||
|
|
||||||
##### options.noInlineConfig
|
##### options.noInlineConfig
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { lint as lintPromise, readConfig as readConfigPromise } from "../../lib/
|
||||||
import { lint as lintSync, readConfig as readConfigSync } from "../../lib/exports-sync.mjs";
|
import { lint as lintSync, readConfig as readConfigSync } from "../../lib/exports-sync.mjs";
|
||||||
|
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import markdownItSub from "markdown-it-sub";
|
import markdownIt from "markdown-it";
|
||||||
const markdownlintJsonPath = "../../.markdownlint.json";
|
const markdownlintJsonPath = "../../.markdownlint.json";
|
||||||
|
|
||||||
const version: string = getVersion();
|
const version: string = getVersion();
|
||||||
|
@ -98,7 +98,7 @@ options = {
|
||||||
"frontMatter": /---/,
|
"frontMatter": /---/,
|
||||||
"handleRuleFailures": false,
|
"handleRuleFailures": false,
|
||||||
"noInlineConfig": false,
|
"noInlineConfig": false,
|
||||||
"markdownItPlugins": [ [ markdownItSub ] ]
|
"markdownItFactory": () => new markdownIt()
|
||||||
};
|
};
|
||||||
|
|
||||||
assertLintResults(lintSync(options));
|
assertLintResults(lintSync(options));
|
||||||
|
|
|
@ -7,6 +7,7 @@ export type LintCallback = import("./markdownlint.mjs").LintCallback;
|
||||||
export type LintContentCallback = import("./markdownlint.mjs").LintContentCallback;
|
export type LintContentCallback = import("./markdownlint.mjs").LintContentCallback;
|
||||||
export type LintError = import("./markdownlint.mjs").LintError;
|
export type LintError = import("./markdownlint.mjs").LintError;
|
||||||
export type LintResults = import("./markdownlint.mjs").LintResults;
|
export type LintResults = import("./markdownlint.mjs").LintResults;
|
||||||
|
export type MarkdownItFactory = import("./markdownlint.mjs").MarkdownItFactory;
|
||||||
export type MarkdownItToken = import("./markdownlint.mjs").MarkdownItToken;
|
export type MarkdownItToken = import("./markdownlint.mjs").MarkdownItToken;
|
||||||
export type MarkdownParsers = import("./markdownlint.mjs").MarkdownParsers;
|
export type MarkdownParsers = import("./markdownlint.mjs").MarkdownParsers;
|
||||||
export type MicromarkToken = import("./markdownlint.mjs").MicromarkToken;
|
export type MicromarkToken = import("./markdownlint.mjs").MicromarkToken;
|
||||||
|
|
|
@ -11,6 +11,7 @@ export { resolveModule } from "./resolve-module.cjs";
|
||||||
/** @typedef {import("./markdownlint.mjs").LintContentCallback} LintContentCallback */
|
/** @typedef {import("./markdownlint.mjs").LintContentCallback} LintContentCallback */
|
||||||
/** @typedef {import("./markdownlint.mjs").LintError} LintError */
|
/** @typedef {import("./markdownlint.mjs").LintError} LintError */
|
||||||
/** @typedef {import("./markdownlint.mjs").LintResults} LintResults */
|
/** @typedef {import("./markdownlint.mjs").LintResults} LintResults */
|
||||||
|
/** @typedef {import("./markdownlint.mjs").MarkdownItFactory} MarkdownItFactory */
|
||||||
/** @typedef {import("./markdownlint.mjs").MarkdownItToken} MarkdownItToken */
|
/** @typedef {import("./markdownlint.mjs").MarkdownItToken} MarkdownItToken */
|
||||||
/** @typedef {import("./markdownlint.mjs").MarkdownParsers} MarkdownParsers */
|
/** @typedef {import("./markdownlint.mjs").MarkdownParsers} MarkdownParsers */
|
||||||
/** @typedef {import("./markdownlint.mjs").MicromarkToken} MicromarkToken */
|
/** @typedef {import("./markdownlint.mjs").MicromarkToken} MicromarkToken */
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
const { newLineRe } = require("../helpers");
|
const { newLineRe } = require("../helpers");
|
||||||
|
|
||||||
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529
|
||||||
|
/** @typedef {import("markdownlint").MarkdownItFactory} MarkdownItFactory */
|
||||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529
|
||||||
/** @typedef {import("markdownlint").MarkdownItToken} MarkdownItToken */
|
/** @typedef {import("markdownlint").MarkdownItToken} MarkdownItToken */
|
||||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529
|
||||||
|
@ -97,7 +99,7 @@ function freezeToken(token) {
|
||||||
/**
|
/**
|
||||||
* Annotate tokens with line/lineNumber and freeze them.
|
* Annotate tokens with line/lineNumber and freeze them.
|
||||||
*
|
*
|
||||||
* @param {Object[]} tokens Array of markdown-it tokens.
|
* @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens.
|
||||||
* @param {string[]} lines Lines of Markdown content.
|
* @param {string[]} lines Lines of Markdown content.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
|
@ -152,21 +154,15 @@ function annotateAndFreezeTokens(tokens, lines) {
|
||||||
/**
|
/**
|
||||||
* Gets an array of markdown-it tokens for the input.
|
* Gets an array of markdown-it tokens for the input.
|
||||||
*
|
*
|
||||||
* @param {Plugin[]} markdownItPlugins Additional plugins.
|
* @param {MarkdownItFactory} markdownItFactory Function to create a markdown-it parser.
|
||||||
* @param {string} content Markdown content.
|
* @param {string} content Markdown content.
|
||||||
* @param {string[]} lines Lines of Markdown content.
|
* @param {string[]} lines Lines of Markdown content.
|
||||||
* @returns {MarkdownItToken} Array of markdown-it tokens.
|
* @returns {MarkdownItToken[]} Array of markdown-it tokens.
|
||||||
*/
|
*/
|
||||||
function getMarkdownItTokens(markdownItPlugins, content, lines) {
|
function getMarkdownItTokens(markdownItFactory, content, lines) {
|
||||||
const markdownit = require("markdown-it");
|
const markdownIt = markdownItFactory();
|
||||||
const md = markdownit({ "html": true });
|
const tokens = markdownIt.parse(content, {});
|
||||||
for (const plugin of markdownItPlugins) {
|
|
||||||
// @ts-ignore
|
|
||||||
md.use(...plugin);
|
|
||||||
}
|
|
||||||
const tokens = md.parse(content, {});
|
|
||||||
annotateAndFreezeTokens(tokens, lines);
|
annotateAndFreezeTokens(tokens, lines);
|
||||||
// @ts-ignore
|
|
||||||
return tokens;
|
return tokens;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -357,6 +357,23 @@ export type Rule = {
|
||||||
*/
|
*/
|
||||||
function: RuleFunction;
|
function: RuleFunction;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Method used by the markdown-it parser to parse input.
|
||||||
|
*/
|
||||||
|
export type MarkdownItParse = (src: string, env: any) => any[];
|
||||||
|
/**
|
||||||
|
* Instance of the markdown-it parser.
|
||||||
|
*/
|
||||||
|
export type MarkdownIt = {
|
||||||
|
/**
|
||||||
|
* Method to parse input.
|
||||||
|
*/
|
||||||
|
parse: MarkdownItParse;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Gets an instance of the markdown-it parser. Any plugins should already have been loaded.
|
||||||
|
*/
|
||||||
|
export type MarkdownItFactory = () => MarkdownIt;
|
||||||
/**
|
/**
|
||||||
* Configuration options.
|
* Configuration options.
|
||||||
*/
|
*/
|
||||||
|
@ -390,9 +407,9 @@ export type Options = {
|
||||||
*/
|
*/
|
||||||
handleRuleFailures?: boolean;
|
handleRuleFailures?: boolean;
|
||||||
/**
|
/**
|
||||||
* Additional plugins.
|
* Function to create a markdown-it parser.
|
||||||
*/
|
*/
|
||||||
markdownItPlugins?: Plugin[];
|
markdownItFactory?: MarkdownItFactory;
|
||||||
/**
|
/**
|
||||||
* True to ignore HTML directives.
|
* True to ignore HTML directives.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -447,7 +447,7 @@ function getEnabledRulesPerLineNumber(
|
||||||
* names.
|
* names.
|
||||||
* @param {string} name Identifier for the content.
|
* @param {string} name Identifier for the content.
|
||||||
* @param {string} content Markdown content.
|
* @param {string} content Markdown content.
|
||||||
* @param {Plugin[]} markdownItPlugins Additional plugins.
|
* @param {MarkdownItFactory} markdownItFactory Function to create a markdown-it parser.
|
||||||
* @param {Configuration} config Configuration object.
|
* @param {Configuration} config Configuration object.
|
||||||
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
||||||
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
||||||
|
@ -462,7 +462,7 @@ function lintContent(
|
||||||
aliasToRuleNames,
|
aliasToRuleNames,
|
||||||
name,
|
name,
|
||||||
content,
|
content,
|
||||||
markdownItPlugins,
|
markdownItFactory,
|
||||||
config,
|
config,
|
||||||
configParsers,
|
configParsers,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
|
@ -502,7 +502,7 @@ function lintContent(
|
||||||
// Parse content into lines and get markdown-it tokens
|
// Parse content into lines and get markdown-it tokens
|
||||||
const lines = content.split(helpers.newLineRe);
|
const lines = content.split(helpers.newLineRe);
|
||||||
const markdownitTokens = needMarkdownItTokens ?
|
const markdownitTokens = needMarkdownItTokens ?
|
||||||
requireMarkdownItCjs().getMarkdownItTokens(markdownItPlugins, preClearedContent, lines) :
|
requireMarkdownItCjs().getMarkdownItTokens(markdownItFactory, preClearedContent, lines) :
|
||||||
[];
|
[];
|
||||||
// Create (frozen) parameters for rules
|
// Create (frozen) parameters for rules
|
||||||
/** @type {MarkdownParsers} */
|
/** @type {MarkdownParsers} */
|
||||||
|
@ -754,10 +754,9 @@ function lintContent(
|
||||||
* Lints a file containing Markdown content.
|
* Lints a file containing Markdown content.
|
||||||
*
|
*
|
||||||
* @param {Rule[]} ruleList List of rules.
|
* @param {Rule[]} ruleList List of rules.
|
||||||
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
|
||||||
* names.
|
|
||||||
* @param {string} file Path of file to lint.
|
* @param {string} file Path of file to lint.
|
||||||
* @param {Plugin[]} markdownItPlugins Additional plugins.
|
* @param {MarkdownItFactory} markdownItFactory Function to create a markdown-it parser.
|
||||||
* @param {Configuration} config Configuration object.
|
* @param {Configuration} config Configuration object.
|
||||||
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
||||||
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
||||||
|
@ -773,7 +772,7 @@ function lintFile(
|
||||||
ruleList,
|
ruleList,
|
||||||
aliasToRuleNames,
|
aliasToRuleNames,
|
||||||
file,
|
file,
|
||||||
markdownItPlugins,
|
markdownItFactory,
|
||||||
config,
|
config,
|
||||||
configParsers,
|
configParsers,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
|
@ -793,7 +792,7 @@ function lintFile(
|
||||||
aliasToRuleNames,
|
aliasToRuleNames,
|
||||||
file,
|
file,
|
||||||
content,
|
content,
|
||||||
markdownItPlugins,
|
markdownItFactory,
|
||||||
config,
|
config,
|
||||||
configParsers,
|
configParsers,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
|
@ -860,7 +859,9 @@ function lintInput(options, synchronous, callback) {
|
||||||
const resultVersion = (options.resultVersion === undefined) ?
|
const resultVersion = (options.resultVersion === undefined) ?
|
||||||
3 :
|
3 :
|
||||||
options.resultVersion;
|
options.resultVersion;
|
||||||
const markdownItPlugins = options.markdownItPlugins || [];
|
const markdownItFactory =
|
||||||
|
options.markdownItFactory ||
|
||||||
|
(() => { throw new Error("The option 'markdownItFactory' was required (due to the option 'customRules' including a rule requiring the 'markdown-it' parser), but 'markdownItFactory' was not set."); });
|
||||||
const fs = options.fs || nodeFs;
|
const fs = options.fs || nodeFs;
|
||||||
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
||||||
const results = newResults(ruleList);
|
const results = newResults(ruleList);
|
||||||
|
@ -892,7 +893,7 @@ function lintInput(options, synchronous, callback) {
|
||||||
ruleList,
|
ruleList,
|
||||||
aliasToRuleNames,
|
aliasToRuleNames,
|
||||||
currentItem,
|
currentItem,
|
||||||
markdownItPlugins,
|
markdownItFactory,
|
||||||
config,
|
config,
|
||||||
configParsers,
|
configParsers,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
|
@ -911,7 +912,7 @@ function lintInput(options, synchronous, callback) {
|
||||||
aliasToRuleNames,
|
aliasToRuleNames,
|
||||||
currentItem,
|
currentItem,
|
||||||
strings[currentItem] || "",
|
strings[currentItem] || "",
|
||||||
markdownItPlugins,
|
markdownItFactory,
|
||||||
config,
|
config,
|
||||||
configParsers,
|
configParsers,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
|
@ -1473,6 +1474,29 @@ export function getVersion() {
|
||||||
* @property {RuleFunction} function Rule implementation.
|
* @property {RuleFunction} function Rule implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used by the markdown-it parser to parse input.
|
||||||
|
*
|
||||||
|
* @callback MarkdownItParse
|
||||||
|
* @param {string} src Source string.
|
||||||
|
* @param {Object} env Environment sandbox.
|
||||||
|
* @returns {import("markdown-it").Token[]} Tokens.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the markdown-it parser.
|
||||||
|
*
|
||||||
|
* @typedef MarkdownIt
|
||||||
|
* @property {MarkdownItParse} parse Method to parse input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance of the markdown-it parser. Any plugins should already have been loaded.
|
||||||
|
*
|
||||||
|
* @callback MarkdownItFactory
|
||||||
|
* @returns {MarkdownIt} Instance of the markdown-it parser.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration options.
|
* Configuration options.
|
||||||
*
|
*
|
||||||
|
@ -1484,7 +1508,7 @@ export function getVersion() {
|
||||||
* @property {RegExp | null} [frontMatter] Front matter pattern.
|
* @property {RegExp | null} [frontMatter] Front matter pattern.
|
||||||
* @property {Object} [fs] File system implementation.
|
* @property {Object} [fs] File system implementation.
|
||||||
* @property {boolean} [handleRuleFailures] True to catch exceptions.
|
* @property {boolean} [handleRuleFailures] True to catch exceptions.
|
||||||
* @property {Plugin[]} [markdownItPlugins] Additional plugins.
|
* @property {MarkdownItFactory} [markdownItFactory] Function to create a markdown-it parser.
|
||||||
* @property {boolean} [noInlineConfig] True to ignore HTML directives.
|
* @property {boolean} [noInlineConfig] True to ignore HTML directives.
|
||||||
* @property {number} [resultVersion] Results object version.
|
* @property {number} [resultVersion] Results object version.
|
||||||
* @property {Object.<string, string>} [strings] Strings to lint.
|
* @property {Object.<string, string>} [strings] Strings to lint.
|
||||||
|
@ -1501,7 +1525,7 @@ export function getVersion() {
|
||||||
*
|
*
|
||||||
* @callback ToStringCallback
|
* @callback ToStringCallback
|
||||||
* @param {boolean} [ruleAliases] True to use rule aliases.
|
* @param {boolean} [ruleAliases] True to use rule aliases.
|
||||||
* @returns {string}
|
* @returns {string} Pretty-printed results.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -73,7 +73,6 @@
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"markdown-it": "14.1.0",
|
|
||||||
"micromark": "4.0.1",
|
"micromark": "4.0.1",
|
||||||
"micromark-core-commonmark": "2.0.2",
|
"micromark-core-commonmark": "2.0.2",
|
||||||
"micromark-extension-directive": "3.0.2",
|
"micromark-extension-directive": "3.0.2",
|
||||||
|
@ -100,6 +99,7 @@
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"json-schema-to-typescript": "15.0.4",
|
"json-schema-to-typescript": "15.0.4",
|
||||||
"jsonc-parser": "3.3.1",
|
"jsonc-parser": "3.3.1",
|
||||||
|
"markdown-it": "14.1.0",
|
||||||
"markdown-it-for-inline": "2.0.1",
|
"markdown-it-for-inline": "2.0.1",
|
||||||
"markdown-it-sub": "2.0.0",
|
"markdown-it-sub": "2.0.0",
|
||||||
"markdown-it-sup": "2.0.0",
|
"markdown-it-sup": "2.0.0",
|
||||||
|
|
|
@ -4,6 +4,7 @@ import fs from "node:fs/promises";
|
||||||
import { createRequire } from "node:module";
|
import { createRequire } from "node:module";
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
import test from "ava";
|
import test from "ava";
|
||||||
|
import markdownIt from "markdown-it";
|
||||||
import { lint as lintAsync } from "markdownlint/async";
|
import { lint as lintAsync } from "markdownlint/async";
|
||||||
import { lint as lintPromise } from "markdownlint/promise";
|
import { lint as lintPromise } from "markdownlint/promise";
|
||||||
import { lint as lintSync } from "markdownlint/sync";
|
import { lint as lintSync } from "markdownlint/sync";
|
||||||
|
@ -13,6 +14,8 @@ import { __filename, importWithTypeJson } from "./esm-helpers.mjs";
|
||||||
const packageJson = await importWithTypeJson(import.meta, "../package.json");
|
const packageJson = await importWithTypeJson(import.meta, "../package.json");
|
||||||
const { homepage, version } = packageJson;
|
const { homepage, version } = packageJson;
|
||||||
|
|
||||||
|
const markdownItFactory = () => markdownIt({ "html": true });
|
||||||
|
|
||||||
test("customRulesV0", (t) => new Promise((resolve) => {
|
test("customRulesV0", (t) => new Promise((resolve) => {
|
||||||
t.plan(4);
|
t.plan(4);
|
||||||
const customRulesMd = "./test/custom-rules.md";
|
const customRulesMd = "./test/custom-rules.md";
|
||||||
|
@ -20,6 +23,7 @@ test("customRulesV0", (t) => new Promise((resolve) => {
|
||||||
const options = {
|
const options = {
|
||||||
"customRules": customRules.all,
|
"customRules": customRules.all,
|
||||||
"files": [ customRulesMd ],
|
"files": [ customRulesMd ],
|
||||||
|
markdownItFactory,
|
||||||
"resultVersion": 0
|
"resultVersion": 0
|
||||||
};
|
};
|
||||||
lintAsync(options, function callback(err, actualResult) {
|
lintAsync(options, function callback(err, actualResult) {
|
||||||
|
@ -92,6 +96,7 @@ test("customRulesV1", (t) => new Promise((resolve) => {
|
||||||
const options = {
|
const options = {
|
||||||
"customRules": customRules.all,
|
"customRules": customRules.all,
|
||||||
"files": [ customRulesMd ],
|
"files": [ customRulesMd ],
|
||||||
|
markdownItFactory,
|
||||||
"resultVersion": 1
|
"resultVersion": 1
|
||||||
};
|
};
|
||||||
lintAsync(options, function callback(err, actualResult) {
|
lintAsync(options, function callback(err, actualResult) {
|
||||||
|
@ -223,6 +228,7 @@ test("customRulesV2", (t) => new Promise((resolve) => {
|
||||||
const options = {
|
const options = {
|
||||||
"customRules": customRules.all,
|
"customRules": customRules.all,
|
||||||
"files": [ customRulesMd ],
|
"files": [ customRulesMd ],
|
||||||
|
markdownItFactory,
|
||||||
"resultVersion": 2
|
"resultVersion": 2
|
||||||
};
|
};
|
||||||
lintAsync(options, function callback(err, actualResult) {
|
lintAsync(options, function callback(err, actualResult) {
|
||||||
|
@ -351,6 +357,7 @@ test("customRulesConfig", (t) => new Promise((resolve) => {
|
||||||
},
|
},
|
||||||
"letters-e-x": false
|
"letters-e-x": false
|
||||||
},
|
},
|
||||||
|
markdownItFactory,
|
||||||
"resultVersion": 0
|
"resultVersion": 0
|
||||||
};
|
};
|
||||||
lintAsync(options, function callback(err, actualResult) {
|
lintAsync(options, function callback(err, actualResult) {
|
||||||
|
@ -376,6 +383,7 @@ test("customRulesNpmPackage", (t) => new Promise((resolve) => {
|
||||||
require("./rules/npm"),
|
require("./rules/npm"),
|
||||||
require("markdownlint-rule-extended-ascii")
|
require("markdownlint-rule-extended-ascii")
|
||||||
],
|
],
|
||||||
|
markdownItFactory,
|
||||||
"strings": {
|
"strings": {
|
||||||
"string": "# Text\n\n---\n\nText ✅\n"
|
"string": "# Text\n\n---\n\nText ✅\n"
|
||||||
},
|
},
|
||||||
|
@ -555,11 +563,12 @@ test("customRulesParserUndefined", (t) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
markdownItFactory,
|
||||||
"strings": {
|
"strings": {
|
||||||
"string": "# Heading\n"
|
"string": "# Heading\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesParserNone", (t) => {
|
test("customRulesParserNone", (t) => {
|
||||||
|
@ -583,7 +592,7 @@ test("customRulesParserNone", (t) => {
|
||||||
"string": "# Heading\n"
|
"string": "# Heading\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesParserMarkdownIt", (t) => {
|
test("customRulesParserMarkdownIt", (t) => {
|
||||||
|
@ -606,11 +615,12 @@ test("customRulesParserMarkdownIt", (t) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
markdownItFactory,
|
||||||
"strings": {
|
"strings": {
|
||||||
"string": "# Heading\n"
|
"string": "# Heading\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesParserMicromark", (t) => {
|
test("customRulesParserMicromark", (t) => {
|
||||||
|
@ -637,7 +647,33 @@ test("customRulesParserMicromark", (t) => {
|
||||||
"string": "# Heading\n"
|
"string": "# Heading\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("customRulesMarkdownItFactoryUndefined", (t) => {
|
||||||
|
t.plan(1);
|
||||||
|
/** @type {import("markdownlint").Options} */
|
||||||
|
const options = {
|
||||||
|
"customRules": [
|
||||||
|
{
|
||||||
|
"names": [ "name" ],
|
||||||
|
"description": "description",
|
||||||
|
"tags": [ "tag" ],
|
||||||
|
"parser": "markdownit",
|
||||||
|
"function": () => {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"strings": {
|
||||||
|
"string": "# Heading\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.throws(
|
||||||
|
() => lintSync(options),
|
||||||
|
{
|
||||||
|
"message": "The option 'markdownItFactory' was required (due to the option 'customRules' including a rule requiring the 'markdown-it' parser), but 'markdownItFactory' was not set."
|
||||||
|
},
|
||||||
|
"No exception when markdownItFactory is undefined."
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesMarkdownItParamsTokensSameObject", (t) => {
|
test("customRulesMarkdownItParamsTokensSameObject", (t) => {
|
||||||
|
@ -657,11 +693,12 @@ test("customRulesMarkdownItParamsTokensSameObject", (t) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
markdownItFactory,
|
||||||
"strings": {
|
"strings": {
|
||||||
"string": "# Heading\n"
|
"string": "# Heading\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesMarkdownItTokensSnapshot", (t) => {
|
test("customRulesMarkdownItTokensSnapshot", (t) => {
|
||||||
|
@ -680,13 +717,14 @@ test("customRulesMarkdownItTokensSnapshot", (t) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
markdownItFactory,
|
||||||
"noInlineConfig": true
|
"noInlineConfig": true
|
||||||
};
|
};
|
||||||
return fs
|
return fs
|
||||||
.readFile("./test/every-markdown-syntax.md", "utf8")
|
.readFile("./test/every-markdown-syntax.md", "utf8")
|
||||||
.then((content) => {
|
.then((content) => {
|
||||||
options.strings = { "content": content.split(newLineRe).join("\n") };
|
options.strings = { "content": content.split(newLineRe).join("\n") };
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -712,7 +750,7 @@ test("customRulesMicromarkTokensSnapshot", (t) => {
|
||||||
.readFile("./test/every-markdown-syntax.md", "utf8")
|
.readFile("./test/every-markdown-syntax.md", "utf8")
|
||||||
.then((content) => {
|
.then((content) => {
|
||||||
options.strings = { "content": content.split(newLineRe).join("\n") };
|
options.strings = { "content": content.split(newLineRe).join("\n") };
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1665,7 +1703,8 @@ test("customRulesLintJavaScript", (t) => new Promise((resolve) => {
|
||||||
/** @type {import("markdownlint").Options} */
|
/** @type {import("markdownlint").Options} */
|
||||||
const options = {
|
const options = {
|
||||||
"customRules": customRules.lintJavaScript,
|
"customRules": customRules.lintJavaScript,
|
||||||
"files": "test/lint-javascript.md"
|
"files": "test/lint-javascript.md",
|
||||||
|
markdownItFactory
|
||||||
};
|
};
|
||||||
lintAsync(options, (err, actual) => {
|
lintAsync(options, (err, actual) => {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
|
@ -1693,7 +1732,8 @@ test("customRulesValidateJson", (t) => new Promise((resolve) => {
|
||||||
/** @type {import("markdownlint").Options} */
|
/** @type {import("markdownlint").Options} */
|
||||||
const options = {
|
const options = {
|
||||||
"customRules": customRules.validateJson,
|
"customRules": customRules.validateJson,
|
||||||
"files": "test/validate-json.md"
|
"files": "test/validate-json.md",
|
||||||
|
markdownItFactory
|
||||||
};
|
};
|
||||||
lintAsync(options, (err, actual) => {
|
lintAsync(options, (err, actual) => {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
|
@ -1792,9 +1832,10 @@ test("customRulesParamsAreFrozen", (t) => {
|
||||||
"function": assertParamsFrozen
|
"function": assertParamsFrozen
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"files": [ "README.md" ]
|
"files": [ "README.md" ],
|
||||||
|
markdownItFactory
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesParamsAreStable", (t) => {
|
test("customRulesParamsAreStable", (t) => {
|
||||||
|
@ -1862,7 +1903,7 @@ test("customRulesParamsAreStable", (t) => {
|
||||||
"string": "# Heading"
|
"string": "# Heading"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return lintPromise(options).then(() => null);
|
return lintPromise(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("customRulesAsyncReadFiles", (t) => {
|
test("customRulesAsyncReadFiles", (t) => {
|
||||||
|
|
|
@ -30,6 +30,23 @@ const ajvOptions = {
|
||||||
"allowUnionTypes": true
|
"allowUnionTypes": true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance of a markdown-it factory, suitable for use with options.markdownItFactory.
|
||||||
|
*
|
||||||
|
* @param {import("../lib/markdownlint.mjs").Plugin[]} markdownItPlugins Additional markdown-it plugins.
|
||||||
|
* @returns {import("../lib/markdownlint.mjs").MarkdownItFactory} Function to create a markdown-it parser.
|
||||||
|
*/
|
||||||
|
function getMarkdownItFactory(markdownItPlugins) {
|
||||||
|
return () => {
|
||||||
|
const md = markdownIt({ "html": true });
|
||||||
|
for (const markdownItPlugin of markdownItPlugins) {
|
||||||
|
// @ts-ignore
|
||||||
|
md.use(...markdownItPlugin);
|
||||||
|
}
|
||||||
|
return md;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
test("simpleAsync", (t) => new Promise((resolve) => {
|
test("simpleAsync", (t) => new Promise((resolve) => {
|
||||||
t.plan(2);
|
t.plan(2);
|
||||||
const options = {
|
const options = {
|
||||||
|
@ -622,7 +639,7 @@ test("readmeHeadings", (t) => new Promise((resolve) => {
|
||||||
"##### options.frontMatter",
|
"##### options.frontMatter",
|
||||||
"##### options.fs",
|
"##### options.fs",
|
||||||
"##### options.handleRuleFailures",
|
"##### options.handleRuleFailures",
|
||||||
"##### options.markdownItPlugins",
|
"##### options.markdownItFactory",
|
||||||
"##### options.noInlineConfig",
|
"##### options.noInlineConfig",
|
||||||
"##### options.resultVersion",
|
"##### options.resultVersion",
|
||||||
"##### options.strings",
|
"##### options.strings",
|
||||||
|
@ -1054,9 +1071,9 @@ test("markdownItPluginsSingle", (t) => new Promise((resolve) => {
|
||||||
},
|
},
|
||||||
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
||||||
"customRules": customRules.anyBlockquote,
|
"customRules": customRules.anyBlockquote,
|
||||||
"markdownItPlugins": [
|
"markdownItFactory": getMarkdownItFactory([
|
||||||
[ pluginInline, "check_text_plugin", "text", () => t.true(true) ]
|
[ pluginInline, "check_text_plugin", "text", () => t.true(true) ]
|
||||||
]
|
])
|
||||||
}, function callback(err, actual) {
|
}, function callback(err, actual) {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
const expected = { "string": [] };
|
const expected = { "string": [] };
|
||||||
|
@ -1073,12 +1090,12 @@ test("markdownItPluginsMultiple", (t) => new Promise((resolve) => {
|
||||||
},
|
},
|
||||||
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
||||||
"customRules": customRules.anyBlockquote,
|
"customRules": customRules.anyBlockquote,
|
||||||
"markdownItPlugins": [
|
"markdownItFactory": getMarkdownItFactory([
|
||||||
[ pluginSub ],
|
[ pluginSub ],
|
||||||
[ pluginSup ],
|
[ pluginSup ],
|
||||||
[ pluginInline, "check_sub_plugin", "sub_open", () => t.true(true) ],
|
[ pluginInline, "check_sub_plugin", "sub_open", () => t.true(true) ],
|
||||||
[ pluginInline, "check_sup_plugin", "sup_open", () => t.true(true) ]
|
[ pluginInline, "check_sup_plugin", "sup_open", () => t.true(true) ]
|
||||||
]
|
])
|
||||||
}, function callback(err, actual) {
|
}, function callback(err, actual) {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
const expected = { "string": [] };
|
const expected = { "string": [] };
|
||||||
|
@ -1093,9 +1110,9 @@ test("markdownItPluginsNoMarkdownIt", (t) => new Promise((resolve) => {
|
||||||
"strings": {
|
"strings": {
|
||||||
"string": "# Heading\n\nText\n"
|
"string": "# Heading\n\nText\n"
|
||||||
},
|
},
|
||||||
"markdownItPlugins": [
|
"markdownItFactory": getMarkdownItFactory([
|
||||||
[ pluginInline, "check_text_plugin", "text", () => t.fail() ]
|
[ pluginInline, "check_text_plugin", "text", () => t.fail() ]
|
||||||
]
|
])
|
||||||
}, function callback(err, actual) {
|
}, function callback(err, actual) {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
const expected = { "string": [] };
|
const expected = { "string": [] };
|
||||||
|
@ -1115,9 +1132,9 @@ test("markdownItPluginsUnusedUncalled", (t) => new Promise((resolve) => {
|
||||||
},
|
},
|
||||||
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
// Use a markdown-it custom rule so the markdown-it plugin will be run
|
||||||
"customRules": customRules.anyBlockquote,
|
"customRules": customRules.anyBlockquote,
|
||||||
"markdownItPlugins": [
|
"markdownItFactory": getMarkdownItFactory([
|
||||||
[ pluginInline, "check_text_plugin", "text", () => t.fail() ]
|
[ pluginInline, "check_text_plugin", "text", () => t.fail() ]
|
||||||
]
|
])
|
||||||
}, function callback(err, actual) {
|
}, function callback(err, actual) {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
const expected = { "string": [] };
|
const expected = { "string": [] };
|
||||||
|
@ -1184,7 +1201,8 @@ test("token-map-spans", (t) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"files": [ "./test/token-map-spans.md" ]
|
"files": [ "./test/token-map-spans.md" ],
|
||||||
|
"markdownItFactory": getMarkdownItFactory([])
|
||||||
};
|
};
|
||||||
lintSync(options);
|
lintSync(options);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue