Reimplement MD040/fenced-code-language using micromark tokens.

This commit is contained in:
David Anson 2024-02-18 17:22:32 -08:00
parent f5b5773b50
commit f26df4743c
5 changed files with 42 additions and 74 deletions

View file

@ -5483,7 +5483,9 @@ module.exports = {
const { addError, addErrorContext, filterTokens } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
const { addError, addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
const { filterByTypes, getTokenTextByType, tokenIfType } =
__webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
module.exports = {
"names": [ "MD040", "fenced-code-language" ],
@ -5493,27 +5495,22 @@ module.exports = {
let allowed = params.config.allowed_languages;
allowed = Array.isArray(allowed) ? allowed : [];
const languageOnly = !!params.config.language_only;
filterTokens(params, "fence", function forToken(token) {
const lang = token.info.trim().split(/\s+/u).shift();
if (lang === "") {
addErrorContext(onError, token.lineNumber, token.line);
} else if ((allowed.length > 0) && !allowed.includes(lang)) {
addError(
onError,
token.lineNumber,
`"${lang}" is not allowed`
);
const fencedCodes = filterByTypes(params.parsers.micromark.tokens, [ "codeFenced" ]);
for (const fencedCode of fencedCodes) {
const openingFence = tokenIfType(fencedCode.children[0], "codeFencedFence");
if (openingFence) {
const { children, startLine, text } = openingFence;
const info = getTokenTextByType(children, "codeFencedFenceInfo")
if (!info) {
addErrorContext(onError, startLine, text);
} else if ((allowed.length > 0) && !allowed.includes(info)) {
addError(onError, startLine, `"${info}" is not allowed`);
}
if (languageOnly && getTokenTextByType(children, "codeFencedFenceMeta")) {
addError(onError, startLine, `Info string contains more than language: "${text}"`);
}
}
if (languageOnly && (token.info !== lang)) {
addError(
onError,
token.lineNumber,
`Info string contains more than language: "${token.info}"`
);
}
});
}
}
};

View file

@ -2,7 +2,9 @@
"use strict";
const { addError, addErrorContext, filterTokens } = require("../helpers");
const { addError, addErrorContext } = require("../helpers");
const { filterByTypes, getTokenTextByType, tokenIfType } =
require("../helpers/micromark.cjs");
module.exports = {
"names": [ "MD040", "fenced-code-language" ],
@ -12,26 +14,21 @@ module.exports = {
let allowed = params.config.allowed_languages;
allowed = Array.isArray(allowed) ? allowed : [];
const languageOnly = !!params.config.language_only;
filterTokens(params, "fence", function forToken(token) {
const lang = token.info.trim().split(/\s+/u).shift();
if (lang === "") {
addErrorContext(onError, token.lineNumber, token.line);
} else if ((allowed.length > 0) && !allowed.includes(lang)) {
addError(
onError,
token.lineNumber,
`"${lang}" is not allowed`
);
const fencedCodes = filterByTypes(params.parsers.micromark.tokens, [ "codeFenced" ]);
for (const fencedCode of fencedCodes) {
const openingFence = tokenIfType(fencedCode.children[0], "codeFencedFence");
if (openingFence) {
const { children, startLine, text } = openingFence;
const info = getTokenTextByType(children, "codeFencedFenceInfo")
if (!info) {
addErrorContext(onError, startLine, text);
} else if ((allowed.length > 0) && !allowed.includes(info)) {
addError(onError, startLine, `"${info}" is not allowed`);
}
if (languageOnly && getTokenTextByType(children, "codeFencedFenceMeta")) {
addError(onError, startLine, `Info string contains more than language: "${text}"`);
}
}
if (languageOnly && (token.info !== lang)) {
addError(
onError,
token.lineNumber,
`Info string contains more than language: "${token.info}"`
);
}
});
}
}
};

View file

@ -3,13 +3,13 @@
Fence code block information with leading whitespace:
``` html
<h1>markdownlint</h1> {MD040:5}
<h1>markdownlint</h1>
```
Fence code block information with trailing whitespace:
```css
body {} {MD040:11} {MD009:11}
body {} {MD009:11}
```
Fence code block information with extra data:

View file

@ -34755,7 +34755,7 @@ Generated by [AVA](https://avajs.dev).
],
},
{
errorContext: ' ```',
errorContext: '```',
errorDetail: null,
errorRange: null,
fixInfo: null,
@ -38128,33 +38128,7 @@ Generated by [AVA](https://avajs.dev).
},
{
errorContext: null,
errorDetail: 'Info string contains more than language: " html"',
errorRange: null,
fixInfo: null,
lineNumber: 5,
ruleDescription: 'Fenced code blocks should have a language specified',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md040.md',
ruleNames: [
'MD040',
'fenced-code-language',
],
},
{
errorContext: null,
errorDetail: 'Info string contains more than language: "css "',
errorRange: null,
fixInfo: null,
lineNumber: 11,
ruleDescription: 'Fenced code blocks should have a language specified',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md040.md',
ruleNames: [
'MD040',
'fenced-code-language',
],
},
{
errorContext: null,
errorDetail: 'Info string contains more than language: "html version=5"',
errorDetail: 'Info string contains more than language: "```html version=5"',
errorRange: null,
fixInfo: null,
lineNumber: 17,
@ -38171,13 +38145,13 @@ Generated by [AVA](https://avajs.dev).
Fence code block information with leading whitespace:␊
\`\`\` html␊
<h1>markdownlint</h1> {MD040:5}
<h1>markdownlint</h1>
\`\`\`␊
Fence code block information with trailing whitespace:␊
\`\`\`css␊
body {} {MD040:11} {MD009:11}␊
body {} {MD009:11}␊
\`\`\`␊
Fence code block information with extra data:␊