Add @stylistic/eslint-plugin to ESLint configuration.

This commit is contained in:
David Anson 2024-09-01 16:16:05 -07:00
parent fe02674ce0
commit 164bbac651
21 changed files with 103 additions and 78 deletions

View file

@ -2540,11 +2540,13 @@ function lintInput(options, synchronous, callback) {
const config = options.config || { "default": true }; const config = options.config || { "default": true };
const configParsers = options.configParsers || null; const configParsers = options.configParsers || null;
const frontMatter = (options.frontMatter === undefined) ? const frontMatter = (options.frontMatter === undefined) ?
helpers.frontMatterRe : options.frontMatter; helpers.frontMatterRe :
options.frontMatter;
const handleRuleFailures = !!options.handleRuleFailures; const handleRuleFailures = !!options.handleRuleFailures;
const noInlineConfig = !!options.noInlineConfig; const noInlineConfig = !!options.noInlineConfig;
const resultVersion = (options.resultVersion === undefined) ? const resultVersion = (options.resultVersion === undefined) ?
3 : options.resultVersion; 3 :
options.resultVersion;
const getMarkdownIt = () => { const getMarkdownIt = () => {
const markdownit = __webpack_require__(/*! markdown-it */ "markdown-it"); const markdownit = __webpack_require__(/*! markdown-it */ "markdown-it");
const md = markdownit({ "html": true }); const md = markdownit({ "html": true });
@ -4027,14 +4029,14 @@ module.exports = {
codeBlock.children, codeBlock.children,
[ "codeFlowValue" ] [ "codeFlowValue" ]
); );
const dollarMatches = codeFlowValues. const dollarMatches = codeFlowValues
map((codeFlowValue) => ({ .map((codeFlowValue) => ({
"result": codeFlowValue.text.match(dollarCommandRe), "result": codeFlowValue.text.match(dollarCommandRe),
"startColumn": codeFlowValue.startColumn, "startColumn": codeFlowValue.startColumn,
"startLine": codeFlowValue.startLine, "startLine": codeFlowValue.startLine,
"text": codeFlowValue.text "text": codeFlowValue.text
})). }))
filter((dollarMatch) => dollarMatch.result); .filter((dollarMatch) => dollarMatch.result);
if (dollarMatches.length === codeFlowValues.length) { if (dollarMatches.length === codeFlowValues.length) {
for (const dollarMatch of dollarMatches) { for (const dollarMatch of dollarMatches) {
// @ts-ignore // @ts-ignore
@ -4647,9 +4649,9 @@ const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache
// eslint-disable-next-line jsdoc/valid-types // eslint-disable-next-line jsdoc/valid-types
/** @type import("./markdownlint").Rule */ /** @type import("./markdownlint").Rule */
module.exports = { module.exports = {
"names": ["MD027", "no-multiple-space-blockquote"], "names": [ "MD027", "no-multiple-space-blockquote" ],
"description": "Multiple spaces after blockquote symbol", "description": "Multiple spaces after blockquote symbol",
"tags": ["blockquote", "whitespace", "indentation"], "tags": [ "blockquote", "whitespace", "indentation" ],
"parser": "micromark", "parser": "micromark",
"function": function MD027(params, onError) { "function": function MD027(params, onError) {
for (const token of filterByTypesCached([ "linePrefix" ])) { for (const token of filterByTypesCached([ "linePrefix" ])) {
@ -4921,10 +4923,12 @@ const codeFencePrefixRe = /^(.*?)[`~]/;
function addError(onError, lines, lineNumber, top) { function addError(onError, lines, lineNumber, top) {
const line = lines[lineNumber - 1]; const line = lines[lineNumber - 1];
const [ , prefix ] = line.match(codeFencePrefixRe) || []; const [ , prefix ] = line.match(codeFencePrefixRe) || [];
const fixInfo = (prefix === undefined) ? null : { const fixInfo = (prefix === undefined) ?
"lineNumber": lineNumber + (top ? 0 : 1), null :
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n` {
}; "lineNumber": lineNumber + (top ? 0 : 1),
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n`
};
addErrorContext( addErrorContext(
onError, onError,
lineNumber, lineNumber,
@ -5122,8 +5126,6 @@ module.exports = {
if ((token.type === "literalAutolink") && !inHtmlFlow(token)) { if ((token.type === "literalAutolink") && !inHtmlFlow(token)) {
// Detect and ignore https://github.com/micromark/micromark/issues/164 // Detect and ignore https://github.com/micromark/micromark/issues/164
const siblings = token.parent?.children; const siblings = token.parent?.children;
// Commented-out due to not being able to exercise in test/code coverage
// || micromarkTokens;
const index = siblings?.indexOf(token); const index = siblings?.indexOf(token);
// @ts-ignore // @ts-ignore
const prev = siblings?.at(index - 1); const prev = siblings?.at(index - 1);
@ -5274,8 +5276,8 @@ module.exports = {
punctuation = String((punctuation === undefined) ? allPunctuation : punctuation); punctuation = String((punctuation === undefined) ? allPunctuation : punctuation);
const punctuationRe = new RegExp("[" + punctuation + "]$"); const punctuationRe = new RegExp("[" + punctuation + "]$");
const paragraphTokens = const paragraphTokens =
filterByTypesCached([ "paragraph" ]). filterByTypesCached([ "paragraph" ])
filter((token) => .filter((token) =>
(token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1) (token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1)
); );
for (const paragraphToken of paragraphTokens) { for (const paragraphToken of paragraphTokens) {
@ -5556,10 +5558,12 @@ function addLabelSpaceError(onError, label, labelText, isStart) {
isStart, isStart,
!isStart, !isStart,
range, range,
range ? { range ?
"editColumn": range[0], {
"deleteCount": range[1] "editColumn": range[0],
} : undefined "deleteCount": range[1]
} :
undefined
); );
} }
@ -5584,8 +5588,8 @@ module.exports = {
"parser": "micromark", "parser": "micromark",
"function": function MD039(params, onError) { "function": function MD039(params, onError) {
const { definitions } = getReferenceLinkImageData(); const { definitions } = getReferenceLinkImageData();
const labels = filterByTypesCached([ "label" ]). const labels = filterByTypesCached([ "label" ])
filter((label) => label.parent?.type === "link"); .filter((label) => label.parent?.type === "link");
for (const label of labels) { for (const label of labels) {
const labelTexts = filterByTypes( const labelTexts = filterByTypes(
label.children, label.children,
@ -5685,9 +5689,9 @@ module.exports = {
"function": function MD041(params, onError) { "function": function MD041(params, onError) {
const level = Number(params.config.level || 1); const level = Number(params.config.level || 1);
if (!frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title)) { if (!frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title)) {
params.parsers.micromark.tokens. params.parsers.micromark.tokens
filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token)). .filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token))
every((token) => { .every((token) => {
let isError = true; let isError = true;
if ((token.type === "atxHeading") || (token.type === "setextHeading")) { if ((token.type === "atxHeading") || (token.type === "setextHeading")) {
isError = (getHeadingLevel(token) !== level); isError = (getHeadingLevel(token) !== level);
@ -6906,7 +6910,7 @@ module.exports = {
} }
} }
} }
} };
/***/ }), /***/ }),

View file

@ -1,14 +1,24 @@
import js from "@eslint/js"; import js from "@eslint/js";
import eslintPluginJsdoc from "eslint-plugin-jsdoc"; import eslintPluginJsdoc from "eslint-plugin-jsdoc";
import eslintPluginNode from "eslint-plugin-n"; import eslintPluginNode from "eslint-plugin-n";
import eslintPluginRegexp from "eslint-plugin-regexp" import eslintPluginRegexp from "eslint-plugin-regexp";
import eslintPluginStylistic from "@stylistic/eslint-plugin";
import eslintPluginUnicorn from "eslint-plugin-unicorn"; import eslintPluginUnicorn from "eslint-plugin-unicorn";
export default [ export default [
js.configs.all, js.configs.all,
eslintPluginJsdoc.configs['flat/recommended'], eslintPluginJsdoc.configs["flat/recommended"],
eslintPluginNode.configs["flat/recommended"], eslintPluginNode.configs["flat/recommended"],
eslintPluginRegexp.configs["flat/recommended"], eslintPluginRegexp.configs["flat/recommended"],
eslintPluginStylistic.configs.customize({
"arrowParens": true,
"braceStyle": "1tbs",
"commaDangle": "never",
"jsx": false,
"quoteProps": "always",
"quotes": "double",
"semi": true
}),
eslintPluginUnicorn.configs["flat/all"], eslintPluginUnicorn.configs["flat/all"],
{ {
"ignores": [ "ignores": [
@ -27,17 +37,23 @@ export default [
}, },
{ {
"languageOptions": { "languageOptions": {
"sourceType": "commonjs", "sourceType": "commonjs"
}, },
"linterOptions": { "linterOptions": {
"reportUnusedDisableDirectives": true "reportUnusedDisableDirectives": true
}, },
"rules": { "rules": {
"@stylistic/array-bracket-spacing": [ "error", "always" ],
"@stylistic/indent": [ "error", 2 ],
"@stylistic/indent-binary-ops": [ "off" ],
"@stylistic/operator-linebreak": [ "error", "after" ],
"@stylistic/padded-blocks": "off",
"@stylistic/space-before-function-paren": [ "error", "never" ],
"capitalized-comments": "off", "capitalized-comments": "off",
"complexity": "off", "complexity": "off",
"func-style": "off", "func-style": "off",
"id-length": "off", "id-length": "off",
"jsdoc/tag-lines": [ "error", "never", { "startLines":1 } ], "jsdoc/tag-lines": [ "error", "never", { "startLines": 1 } ],
"logical-assignment-operators": "off", "logical-assignment-operators": "off",
"max-depth": "off", "max-depth": "off",
"max-lines-per-function": "off", "max-lines-per-function": "off",

View file

@ -932,11 +932,13 @@ function lintInput(options, synchronous, callback) {
const config = options.config || { "default": true }; const config = options.config || { "default": true };
const configParsers = options.configParsers || null; const configParsers = options.configParsers || null;
const frontMatter = (options.frontMatter === undefined) ? const frontMatter = (options.frontMatter === undefined) ?
helpers.frontMatterRe : options.frontMatter; helpers.frontMatterRe :
options.frontMatter;
const handleRuleFailures = !!options.handleRuleFailures; const handleRuleFailures = !!options.handleRuleFailures;
const noInlineConfig = !!options.noInlineConfig; const noInlineConfig = !!options.noInlineConfig;
const resultVersion = (options.resultVersion === undefined) ? const resultVersion = (options.resultVersion === undefined) ?
3 : options.resultVersion; 3 :
options.resultVersion;
const getMarkdownIt = () => { const getMarkdownIt = () => {
const markdownit = require("markdown-it"); const markdownit = require("markdown-it");
const md = markdownit({ "html": true }); const md = markdownit({ "html": true });

View file

@ -21,14 +21,14 @@ module.exports = {
codeBlock.children, codeBlock.children,
[ "codeFlowValue" ] [ "codeFlowValue" ]
); );
const dollarMatches = codeFlowValues. const dollarMatches = codeFlowValues
map((codeFlowValue) => ({ .map((codeFlowValue) => ({
"result": codeFlowValue.text.match(dollarCommandRe), "result": codeFlowValue.text.match(dollarCommandRe),
"startColumn": codeFlowValue.startColumn, "startColumn": codeFlowValue.startColumn,
"startLine": codeFlowValue.startLine, "startLine": codeFlowValue.startLine,
"text": codeFlowValue.text "text": codeFlowValue.text
})). }))
filter((dollarMatch) => dollarMatch.result); .filter((dollarMatch) => dollarMatch.result);
if (dollarMatches.length === codeFlowValues.length) { if (dollarMatches.length === codeFlowValues.length) {
for (const dollarMatch of dollarMatches) { for (const dollarMatch of dollarMatches) {
// @ts-ignore // @ts-ignore

View file

@ -8,9 +8,9 @@ const { filterByTypesCached } = require("./cache");
// eslint-disable-next-line jsdoc/valid-types // eslint-disable-next-line jsdoc/valid-types
/** @type import("./markdownlint").Rule */ /** @type import("./markdownlint").Rule */
module.exports = { module.exports = {
"names": ["MD027", "no-multiple-space-blockquote"], "names": [ "MD027", "no-multiple-space-blockquote" ],
"description": "Multiple spaces after blockquote symbol", "description": "Multiple spaces after blockquote symbol",
"tags": ["blockquote", "whitespace", "indentation"], "tags": [ "blockquote", "whitespace", "indentation" ],
"parser": "micromark", "parser": "micromark",
"function": function MD027(params, onError) { "function": function MD027(params, onError) {
for (const token of filterByTypesCached([ "linePrefix" ])) { for (const token of filterByTypesCached([ "linePrefix" ])) {

View file

@ -23,10 +23,12 @@ const codeFencePrefixRe = /^(.*?)[`~]/;
function addError(onError, lines, lineNumber, top) { function addError(onError, lines, lineNumber, top) {
const line = lines[lineNumber - 1]; const line = lines[lineNumber - 1];
const [ , prefix ] = line.match(codeFencePrefixRe) || []; const [ , prefix ] = line.match(codeFencePrefixRe) || [];
const fixInfo = (prefix === undefined) ? null : { const fixInfo = (prefix === undefined) ?
"lineNumber": lineNumber + (top ? 0 : 1), null :
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n` {
}; "lineNumber": lineNumber + (top ? 0 : 1),
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n`
};
addErrorContext( addErrorContext(
onError, onError,
lineNumber, lineNumber,

View file

@ -21,8 +21,6 @@ module.exports = {
if ((token.type === "literalAutolink") && !inHtmlFlow(token)) { if ((token.type === "literalAutolink") && !inHtmlFlow(token)) {
// Detect and ignore https://github.com/micromark/micromark/issues/164 // Detect and ignore https://github.com/micromark/micromark/issues/164
const siblings = token.parent?.children; const siblings = token.parent?.children;
// Commented-out due to not being able to exercise in test/code coverage
// || micromarkTokens;
const index = siblings?.indexOf(token); const index = siblings?.indexOf(token);
// @ts-ignore // @ts-ignore
const prev = siblings?.at(index - 1); const prev = siblings?.at(index - 1);

View file

@ -25,8 +25,8 @@ module.exports = {
punctuation = String((punctuation === undefined) ? allPunctuation : punctuation); punctuation = String((punctuation === undefined) ? allPunctuation : punctuation);
const punctuationRe = new RegExp("[" + punctuation + "]$"); const punctuationRe = new RegExp("[" + punctuation + "]$");
const paragraphTokens = const paragraphTokens =
filterByTypesCached([ "paragraph" ]). filterByTypesCached([ "paragraph" ])
filter((token) => .filter((token) =>
(token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1) (token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1)
); );
for (const paragraphToken of paragraphTokens) { for (const paragraphToken of paragraphTokens) {

View file

@ -29,10 +29,12 @@ function addLabelSpaceError(onError, label, labelText, isStart) {
isStart, isStart,
!isStart, !isStart,
range, range,
range ? { range ?
"editColumn": range[0], {
"deleteCount": range[1] "editColumn": range[0],
} : undefined "deleteCount": range[1]
} :
undefined
); );
} }
@ -57,8 +59,8 @@ module.exports = {
"parser": "micromark", "parser": "micromark",
"function": function MD039(params, onError) { "function": function MD039(params, onError) {
const { definitions } = getReferenceLinkImageData(); const { definitions } = getReferenceLinkImageData();
const labels = filterByTypesCached([ "label" ]). const labels = filterByTypesCached([ "label" ])
filter((label) => label.parent?.type === "link"); .filter((label) => label.parent?.type === "link");
for (const label of labels) { for (const label of labels) {
const labelTexts = filterByTypes( const labelTexts = filterByTypes(
label.children, label.children,

View file

@ -16,9 +16,9 @@ module.exports = {
"function": function MD041(params, onError) { "function": function MD041(params, onError) {
const level = Number(params.config.level || 1); const level = Number(params.config.level || 1);
if (!frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title)) { if (!frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title)) {
params.parsers.micromark.tokens. params.parsers.micromark.tokens
filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token)). .filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token))
every((token) => { .every((token) => {
let isError = true; let isError = true;
if ((token.type === "atxHeading") || (token.type === "setextHeading")) { if ((token.type === "atxHeading") || (token.type === "setextHeading")) {
isError = (getHeadingLevel(token) !== level); isError = (getHeadingLevel(token) !== level);

View file

@ -53,4 +53,4 @@ module.exports = {
} }
} }
} }
} };

View file

@ -70,6 +70,7 @@
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "9.9.1", "@eslint/js": "9.9.1",
"@stylistic/eslint-plugin": "2.7.2",
"ajv": "8.17.1", "ajv": "8.17.1",
"ava": "6.1.3", "ava": "6.1.3",
"c8": "10.1.2", "c8": "10.1.2",

View file

@ -529,7 +529,7 @@ for (const rule of rules) {
"description": "Allow URLs as inline links", "description": "Allow URLs as inline links",
"type": "boolean", "type": "boolean",
"default": true "default": true
}, }
}; };
break; break;
case "MD055": case "MD055":

View file

@ -77,8 +77,8 @@ test("filterByTypes, htmlFlow false", async(t) => {
// Not using flat tokens // Not using flat tokens
t.deepEqual( t.deepEqual(
filtered, filtered,
filterByTypes([ ...tokens], types) filterByTypes([ ...tokens ], types)
) );
}); });
test("filterByTypes, htmlFlow true", async(t) => { test("filterByTypes, htmlFlow true", async(t) => {
@ -95,8 +95,8 @@ test("filterByTypes, htmlFlow true", async(t) => {
// Not using flat tokens // Not using flat tokens
t.deepEqual( t.deepEqual(
filtered, filtered,
filterByTypes([ ...tokens], types, true) filterByTypes([ ...tokens ], types, true)
) );
}); });
test("filterByPredicate/filterByTypes", async(t) => { test("filterByPredicate/filterByTypes", async(t) => {

View file

@ -23,7 +23,7 @@ function markdownlintParallel(options) {
const workerData = { const workerData = {
...options, ...options,
"files": files.slice(i * chunkSize, (i + 1) * chunkSize) "files": files.slice(i * chunkSize, (i + 1) * chunkSize)
} };
const worker = new Worker(__filename.replace(/parallel\.js$/, "worker.js"), { workerData }); const worker = new Worker(__filename.replace(/parallel\.js$/, "worker.js"), { workerData });
worker.on("message", resolve); worker.on("message", resolve);
worker.on("error", reject); worker.on("error", reject);

View file

@ -33,8 +33,8 @@ async function lintTestRepo(t, globPatterns, configPath, parallel) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(`${t.title}: Linting ${files.length} files...`); console.log(`${t.title}: Linting ${files.length} files...`);
const config = Object.fromEntries( const config = Object.fromEntries(
Object.entries(rawConfig). Object.entries(rawConfig)
map(([ k, v ]) => [ .map(([ k, v ]) => [
k.replace(/header/, "heading"), k.replace(/header/, "heading"),
v v
]) ])

View file

@ -64,8 +64,8 @@ test("resultFormattingV0", (t) => new Promise((resolve) => {
"./test/atx_heading_spacing.md: 1: MD041" + "./test/atx_heading_spacing.md: 1: MD041" +
" First line in a file should be a top-level heading\n" + " First line in a file should be a top-level heading\n" +
"./test/first_heading_bad_atx.md: 1: MD041" + "./test/first_heading_bad_atx.md: 1: MD041" +
" First line in a file should be a top-level heading" " First line in a file should be a top-level heading";
t.is(actualMessage, expectedMessage, "Incorrect message (name)."); t.is(actualMessage, expectedMessage, "Incorrect message (name).");
// @ts-ignore // @ts-ignore
actualMessage = actualResult.toString(true); actualMessage = actualResult.toString(true);
expectedMessage = expectedMessage =
@ -78,8 +78,8 @@ test("resultFormattingV0", (t) => new Promise((resolve) => {
"./test/atx_heading_spacing.md: 1: first-line-heading" + "./test/atx_heading_spacing.md: 1: first-line-heading" +
" First line in a file should be a top-level heading\n" + " First line in a file should be a top-level heading\n" +
"./test/first_heading_bad_atx.md: 1: first-line-heading" + "./test/first_heading_bad_atx.md: 1: first-line-heading" +
" First line in a file should be a top-level heading" " First line in a file should be a top-level heading";
t.is(actualMessage, expectedMessage, "Incorrect message (alias)."); t.is(actualMessage, expectedMessage, "Incorrect message (alias).");
resolve(); resolve();
}); });
})); }));
@ -121,7 +121,7 @@ test("resultFormattingSyncV0", (t) => {
"./test/atx_heading_spacing.md: 1: MD041" + "./test/atx_heading_spacing.md: 1: MD041" +
" First line in a file should be a top-level heading\n" + " First line in a file should be a top-level heading\n" +
"./test/first_heading_bad_atx.md: 1: MD041" + "./test/first_heading_bad_atx.md: 1: MD041" +
" First line in a file should be a top-level heading" " First line in a file should be a top-level heading";
t.is(actualMessage, expectedMessage, "Incorrect message (name)."); t.is(actualMessage, expectedMessage, "Incorrect message (name).");
// @ts-ignore // @ts-ignore
actualMessage = actualResult.toString(true); actualMessage = actualResult.toString(true);
@ -135,7 +135,7 @@ test("resultFormattingSyncV0", (t) => {
"./test/atx_heading_spacing.md: 1: first-line-heading" + "./test/atx_heading_spacing.md: 1: first-line-heading" +
" First line in a file should be a top-level heading\n" + " First line in a file should be a top-level heading\n" +
"./test/first_heading_bad_atx.md: 1: first-line-heading" + "./test/first_heading_bad_atx.md: 1: first-line-heading" +
" First line in a file should be a top-level heading" " First line in a file should be a top-level heading";
t.is(actualMessage, expectedMessage, "Incorrect message (alias)."); t.is(actualMessage, expectedMessage, "Incorrect message (alias).");
}); });

View file

@ -8,9 +8,9 @@ const markdownlint = require("../lib/markdownlint").promises.markdownlint;
// eslint-disable-next-line unicorn/prefer-top-level-await // eslint-disable-next-line unicorn/prefer-top-level-await
markdownlint(workerData).then((lintResults) => { markdownlint(workerData).then((lintResults) => {
// @ts-ignore // @ts-ignore
parentPort. parentPort
// eslint-disable-next-line unicorn/require-post-message-target-origin // eslint-disable-next-line unicorn/require-post-message-target-origin
postMessage(lintResults); .postMessage(lintResults);
// eslint-disable-next-line n/no-process-exit // eslint-disable-next-line n/no-process-exit
process.exit(); process.exit();
}); });

View file

@ -13,8 +13,8 @@ module.exports = {
"tags": [ "test" ], "tags": [ "test" ],
"parser": "markdownit", "parser": "markdownit",
"function": (params, onError) => { "function": (params, onError) => {
const blockquotes = params.parsers.markdownit.tokens. const blockquotes = params.parsers.markdownit.tokens
filter((token => token.type === "blockquote_open")); .filter(((token) => token.type === "blockquote_open"));
for (const blockquote of blockquotes) { for (const blockquote of blockquotes) {
const lines = blockquote.map[1] - blockquote.map[0]; const lines = blockquote.map[1] - blockquote.map[0];
onError({ onError({

View file

@ -14,8 +14,8 @@ module.exports = {
"tags": [ "test", "lint", "javascript" ], "tags": [ "test", "lint", "javascript" ],
"parser": "markdownit", "parser": "markdownit",
"function": (params, onError) => { "function": (params, onError) => {
const fences = params.parsers.markdownit.tokens. const fences = params.parsers.markdownit.tokens
filter((token => token.type === "fence")); .filter(((token) => token.type === "fence"));
for (const fence of fences) { for (const fence of fences) {
if (languageJavaScript.test(fence.info)) { if (languageJavaScript.test(fence.info)) {
const results = linter.verify(fence.content, js.configs.recommended); const results = linter.verify(fence.content, js.configs.recommended);

View file

@ -12,8 +12,8 @@ module.exports = {
"parser": "markdownit", "parser": "markdownit",
"asynchronous": true, "asynchronous": true,
"function": (params, onError) => { "function": (params, onError) => {
const fences = params.parsers.markdownit.tokens. const fences = params.parsers.markdownit.tokens
filter((token => token.type === "fence")); .filter(((token) => token.type === "fence"));
for (const fence of fences) { for (const fence of fences) {
if (/jsonc?/i.test(fence.info)) { if (/jsonc?/i.test(fence.info)) {
const errors = []; const errors = [];