Reimplement MD049/emphasis-style, MD050/strong-style to use micromark parser (with smaller ranges and handling of multi-line fixes).

This commit is contained in:
David Anson 2023-05-25 03:47:34 +00:00
parent e1233aad4b
commit 7005a8a438
9 changed files with 1211 additions and 348 deletions

View file

@ -3,7 +3,7 @@
"use strict";
const { addErrorContext } = require("../helpers");
const { filterByTypes } = require("../helpers/micromark.cjs");
const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs");
const leftSpaceRe = /^\s(?:[^`]|$)/;
const rightSpaceRe = /[^`]\s$/;
@ -17,7 +17,6 @@ const trimCodeText = (text, start, end) => {
}
return text;
};
const tokenIfType = (token, type) => token && (token.type === type) && token;
module.exports = {
"names": [ "MD038", "no-space-in-code" ],

View file

@ -2,54 +2,41 @@
"use strict";
const { addError, emphasisOrStrongStyleFor, forEachInlineChild,
getNextChildToken, getRangeAndFixInfoIfFound } = require("../helpers");
const { addError, emphasisOrStrongStyleFor } = require("../helpers");
const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs");
const impl =
(params, onError, tagPrefix, asterisk, underline, style = "consistent") => {
let lastLineNumber = -1;
const instances = new Map();
forEachInlineChild(params, `${tagPrefix}_open`, (token, parent) => {
const { lineNumber, markup } = token;
const markupStyle = emphasisOrStrongStyleFor(markup);
if (style === "consistent") {
style = markupStyle;
}
if (style !== markupStyle) {
let rangeAndFixInfo = {};
const contentToken = getNextChildToken(
parent, token, "text", `${tagPrefix}_close`
);
if (contentToken) {
const { content } = contentToken;
const actual = `${markup}${content}${markup}`;
const expectedMarkup =
(style === "asterisk") ? asterisk : underline;
const expected = `${expectedMarkup}${content}${expectedMarkup}`;
if (lastLineNumber !== lineNumber) {
lastLineNumber = lineNumber;
instances.clear();
}
const instance = (instances.get(expected) || 0) + 1;
instances.set(expected, instance);
rangeAndFixInfo = getRangeAndFixInfoIfFound(
params.lines,
lineNumber - 1,
actual,
expected,
instance
);
(params, onError, type, asterisk, underline, style = "consistent") => {
const emphasisTokens =
filterByTypes(params.parsers.micromark.tokens, [ type ]);
for (const token of emphasisTokens) {
const { children } = token;
const childType = `${type}Sequence`;
const startSequence = tokenIfType(children[0], childType);
const endSequence = tokenIfType(children[children.length - 1], childType);
if (startSequence && endSequence) {
const markupStyle = emphasisOrStrongStyleFor(startSequence.text);
if (style === "consistent") {
style = markupStyle;
}
if (style !== markupStyle) {
for (const sequence of [ startSequence, endSequence ]) {
addError(
onError,
sequence.startLine,
`Expected: ${style}; Actual: ${markupStyle}`,
undefined,
[ sequence.startColumn, sequence.text.length ],
{
"editColumn": sequence.startColumn,
"deleteCount": sequence.text.length,
"insertText": (style === "asterisk") ? asterisk : underline
}
);
}
}
addError(
onError,
lineNumber,
`Expected: ${style}; Actual: ${markupStyle}`,
undefined,
rangeAndFixInfo.range,
rangeAndFixInfo.fixInfo
);
}
});
}
};
module.exports = [
@ -61,7 +48,7 @@ module.exports = [
return impl(
params,
onError,
"em",
"emphasis",
"*",
"_",
params.config.style || undefined