Update MD049/emphasis-style and MD050/strong-style to correctly report and fix multiple identical violations on the same line (fixes #486).

This commit is contained in:
David Anson 2022-05-03 21:35:31 -07:00
parent 54369a00e6
commit c4f51090ae
8 changed files with 258 additions and 42 deletions

View file

@ -927,12 +927,19 @@ module.exports.applyFixes = applyFixes;
* @param {number} lineIndex Line index to check. * @param {number} lineIndex Line index to check.
* @param {string} search Text to search for. * @param {string} search Text to search for.
* @param {string} replace Text to replace with. * @param {string} replace Text to replace with.
* @param {number} [instance] Instance on the line (1-based).
* @returns {Object} Range and fixInfo wrapper. * @returns {Object} Range and fixInfo wrapper.
*/ */
function getRangeAndFixInfoIfFound(lines, lineIndex, search, replace) { module.exports.getRangeAndFixInfoIfFound =
function (lines, lineIndex, search, replace, instance) {
if (instance === void 0) { instance = 1; }
var range = null; var range = null;
var fixInfo = null; var fixInfo = null;
var searchIndex = lines[lineIndex].indexOf(search); var searchIndex = -1;
while (instance > 0) {
searchIndex = lines[lineIndex].indexOf(search, searchIndex + 1);
instance--;
}
if (searchIndex !== -1) { if (searchIndex !== -1) {
var column = searchIndex + 1; var column = searchIndex + 1;
var length = search.length; var length = search.length;
@ -947,8 +954,7 @@ function getRangeAndFixInfoIfFound(lines, lineIndex, search, replace) {
range: range, range: range,
fixInfo: fixInfo fixInfo: fixInfo
}; };
} };
module.exports.getRangeAndFixInfoIfFound = getRangeAndFixInfoIfFound;
/** /**
* Gets the next (subsequent) child token if it is of the expected type. * Gets the next (subsequent) child token if it is of the expected type.
* *
@ -4411,6 +4417,8 @@ module.exports = {
"tags": ["emphasis"], "tags": ["emphasis"],
"function": function MD049(params, onError) { "function": function MD049(params, onError) {
var expectedStyle = String(params.config.style || "consistent"); var expectedStyle = String(params.config.style || "consistent");
var lastLineNumber = -1;
var instances = new Map();
forEachInlineChild(params, "em_open", function (token, parent) { forEachInlineChild(params, "em_open", function (token, parent) {
var lineNumber = token.lineNumber, markup = token.markup; var lineNumber = token.lineNumber, markup = token.markup;
var markupStyle = emphasisOrStrongStyleFor(markup); var markupStyle = emphasisOrStrongStyleFor(markup);
@ -4425,7 +4433,12 @@ module.exports = {
var actual = "".concat(markup).concat(content).concat(markup); var actual = "".concat(markup).concat(content).concat(markup);
var expectedMarkup = (expectedStyle === "asterisk") ? "*" : "_"; var expectedMarkup = (expectedStyle === "asterisk") ? "*" : "_";
var expected = "".concat(expectedMarkup).concat(content).concat(expectedMarkup); var expected = "".concat(expectedMarkup).concat(content).concat(expectedMarkup);
rangeAndFixInfo = getRangeAndFixInfoIfFound(params.lines, lineNumber - 1, actual, expected); if (lastLineNumber !== lineNumber) {
lastLineNumber = lineNumber;
instances.clear();
}
instances.set(expected, (instances.get(expected) || 0) + 1);
rangeAndFixInfo = getRangeAndFixInfoIfFound(params.lines, lineNumber - 1, actual, expected, instances.get(expected));
} }
addError(onError, lineNumber, "Expected: ".concat(expectedStyle, "; Actual: ").concat(markupStyle), null, rangeAndFixInfo.range, rangeAndFixInfo.fixInfo); addError(onError, lineNumber, "Expected: ".concat(expectedStyle, "; Actual: ").concat(markupStyle), null, rangeAndFixInfo.range, rangeAndFixInfo.fixInfo);
} }
@ -4452,6 +4465,8 @@ module.exports = {
"tags": ["emphasis"], "tags": ["emphasis"],
"function": function MD050(params, onError) { "function": function MD050(params, onError) {
var expectedStyle = String(params.config.style || "consistent"); var expectedStyle = String(params.config.style || "consistent");
var lastLineNumber = -1;
var instances = new Map();
forEachInlineChild(params, "strong_open", function (token, parent) { forEachInlineChild(params, "strong_open", function (token, parent) {
var lineNumber = token.lineNumber, markup = token.markup; var lineNumber = token.lineNumber, markup = token.markup;
var markupStyle = emphasisOrStrongStyleFor(markup); var markupStyle = emphasisOrStrongStyleFor(markup);
@ -4466,7 +4481,12 @@ module.exports = {
var actual = "".concat(markup).concat(content).concat(markup); var actual = "".concat(markup).concat(content).concat(markup);
var expectedMarkup = (expectedStyle === "asterisk") ? "**" : "__"; var expectedMarkup = (expectedStyle === "asterisk") ? "**" : "__";
var expected = "".concat(expectedMarkup).concat(content).concat(expectedMarkup); var expected = "".concat(expectedMarkup).concat(content).concat(expectedMarkup);
rangeAndFixInfo = getRangeAndFixInfoIfFound(params.lines, lineNumber - 1, actual, expected); if (lastLineNumber !== lineNumber) {
lastLineNumber = lineNumber;
instances.clear();
}
instances.set(expected, (instances.get(expected) || 0) + 1);
rangeAndFixInfo = getRangeAndFixInfoIfFound(params.lines, lineNumber - 1, actual, expected, instances.get(expected));
} }
addError(onError, lineNumber, "Expected: ".concat(expectedStyle, "; Actual: ").concat(markupStyle), null, rangeAndFixInfo.range, rangeAndFixInfo.fixInfo); addError(onError, lineNumber, "Expected: ".concat(expectedStyle, "; Actual: ").concat(markupStyle), null, rangeAndFixInfo.range, rangeAndFixInfo.fixInfo);
} }

View file

@ -950,12 +950,18 @@ module.exports.applyFixes = applyFixes;
* @param {number} lineIndex Line index to check. * @param {number} lineIndex Line index to check.
* @param {string} search Text to search for. * @param {string} search Text to search for.
* @param {string} replace Text to replace with. * @param {string} replace Text to replace with.
* @param {number} [instance] Instance on the line (1-based).
* @returns {Object} Range and fixInfo wrapper. * @returns {Object} Range and fixInfo wrapper.
*/ */
function getRangeAndFixInfoIfFound(lines, lineIndex, search, replace) { module.exports.getRangeAndFixInfoIfFound =
(lines, lineIndex, search, replace, instance = 1) => {
let range = null; let range = null;
let fixInfo = null; let fixInfo = null;
const searchIndex = lines[lineIndex].indexOf(search); let searchIndex = -1;
while (instance > 0) {
searchIndex = lines[lineIndex].indexOf(search, searchIndex + 1);
instance--;
}
if (searchIndex !== -1) { if (searchIndex !== -1) {
const column = searchIndex + 1; const column = searchIndex + 1;
const length = search.length; const length = search.length;
@ -970,8 +976,7 @@ function getRangeAndFixInfoIfFound(lines, lineIndex, search, replace) {
range, range,
fixInfo fixInfo
}; };
} };
module.exports.getRangeAndFixInfoIfFound = getRangeAndFixInfoIfFound;
/** /**
* Gets the next (subsequent) child token if it is of the expected type. * Gets the next (subsequent) child token if it is of the expected type.

View file

@ -11,6 +11,8 @@ module.exports = {
"tags": [ "emphasis" ], "tags": [ "emphasis" ],
"function": function MD049(params, onError) { "function": function MD049(params, onError) {
let expectedStyle = String(params.config.style || "consistent"); let expectedStyle = String(params.config.style || "consistent");
let lastLineNumber = -1;
const instances = new Map();
forEachInlineChild(params, "em_open", (token, parent) => { forEachInlineChild(params, "em_open", (token, parent) => {
const { lineNumber, markup } = token; const { lineNumber, markup } = token;
const markupStyle = emphasisOrStrongStyleFor(markup); const markupStyle = emphasisOrStrongStyleFor(markup);
@ -27,8 +29,17 @@ module.exports = {
const actual = `${markup}${content}${markup}`; const actual = `${markup}${content}${markup}`;
const expectedMarkup = (expectedStyle === "asterisk") ? "*" : "_"; const expectedMarkup = (expectedStyle === "asterisk") ? "*" : "_";
const expected = `${expectedMarkup}${content}${expectedMarkup}`; const expected = `${expectedMarkup}${content}${expectedMarkup}`;
if (lastLineNumber !== lineNumber) {
lastLineNumber = lineNumber;
instances.clear();
}
instances.set(expected, (instances.get(expected) || 0) + 1);
rangeAndFixInfo = getRangeAndFixInfoIfFound( rangeAndFixInfo = getRangeAndFixInfoIfFound(
params.lines, lineNumber - 1, actual, expected params.lines,
lineNumber - 1,
actual,
expected,
instances.get(expected)
); );
} }
addError( addError(

View file

@ -11,6 +11,8 @@ module.exports = {
"tags": [ "emphasis" ], "tags": [ "emphasis" ],
"function": function MD050(params, onError) { "function": function MD050(params, onError) {
let expectedStyle = String(params.config.style || "consistent"); let expectedStyle = String(params.config.style || "consistent");
let lastLineNumber = -1;
const instances = new Map();
forEachInlineChild(params, "strong_open", (token, parent) => { forEachInlineChild(params, "strong_open", (token, parent) => {
const { lineNumber, markup } = token; const { lineNumber, markup } = token;
const markupStyle = emphasisOrStrongStyleFor(markup); const markupStyle = emphasisOrStrongStyleFor(markup);
@ -27,8 +29,17 @@ module.exports = {
const actual = `${markup}${content}${markup}`; const actual = `${markup}${content}${markup}`;
const expectedMarkup = (expectedStyle === "asterisk") ? "**" : "__"; const expectedMarkup = (expectedStyle === "asterisk") ? "**" : "__";
const expected = `${expectedMarkup}${content}${expectedMarkup}`; const expected = `${expectedMarkup}${content}${expectedMarkup}`;
if (lastLineNumber !== lineNumber) {
lastLineNumber = lineNumber;
instances.clear();
}
instances.set(expected, (instances.get(expected) || 0) + 1);
rangeAndFixInfo = getRangeAndFixInfoIfFound( rangeAndFixInfo = getRangeAndFixInfoIfFound(
params.lines, lineNumber - 1, actual, expected params.lines,
lineNumber - 1,
actual,
expected,
instances.get(expected)
); );
} }
addError( addError(

View file

@ -1,5 +1,6 @@
{ {
"default": true, "default": true,
"MD013": false,
"MD043": { "MD043": {
"headings": [ "headings": [
"# Heading" "# Heading"

View file

@ -42,4 +42,8 @@ strong **emphasis
spanning** many spanning** many
lines lines
Inconsistent _double_ text _interleaved_ text _double_ _interleaved_ emphasis.
Inconsistent **double** text **interleaved** text **double** **interleaved** strong emphasis.
Missing newline character Missing newline character

View file

@ -42,4 +42,8 @@ strong **emphasis
spanning** many spanning** many
lines lines
Inconsistent *double* text *interleaved* text *double* *interleaved* emphasis.
Inconsistent __double__ text __interleaved__ text __double__ __interleaved__ strong emphasis.
Missing newline character Missing newline character

View file

@ -78,7 +78,7 @@
"fixInfo": null "fixInfo": null
}, },
{ {
"lineNumber": 45, "lineNumber": 49,
"ruleNames": [ "ruleNames": [
"MD043", "MD043",
"required-headings", "required-headings",
@ -178,7 +178,7 @@
"fixInfo": null "fixInfo": null
}, },
{ {
"lineNumber": 45, "lineNumber": 49,
"ruleNames": [ "ruleNames": [
"MD047", "MD047",
"single-trailing-newline" "single-trailing-newline"
@ -262,6 +262,86 @@
"emphasis-style" "emphasis-style"
] ]
}, },
{
"errorContext": null,
"errorDetail": "Expected: asterisk; Actual: underscore",
"errorRange": [
14,
8
],
"fixInfo": {
"deleteCount": 8,
"editColumn": 14,
"insertText": "*double*"
},
"lineNumber": 45,
"ruleDescription": "Emphasis style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md049",
"ruleNames": [
"MD049",
"emphasis-style"
]
},
{
"errorContext": null,
"errorDetail": "Expected: asterisk; Actual: underscore",
"errorRange": [
28,
13
],
"fixInfo": {
"deleteCount": 13,
"editColumn": 28,
"insertText": "*interleaved*"
},
"lineNumber": 45,
"ruleDescription": "Emphasis style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md049",
"ruleNames": [
"MD049",
"emphasis-style"
]
},
{
"errorContext": null,
"errorDetail": "Expected: asterisk; Actual: underscore",
"errorRange": [
47,
8
],
"fixInfo": {
"deleteCount": 8,
"editColumn": 47,
"insertText": "*double*"
},
"lineNumber": 45,
"ruleDescription": "Emphasis style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md049",
"ruleNames": [
"MD049",
"emphasis-style"
]
},
{
"errorContext": null,
"errorDetail": "Expected: asterisk; Actual: underscore",
"errorRange": [
56,
13
],
"fixInfo": {
"deleteCount": 13,
"editColumn": 56,
"insertText": "*interleaved*"
},
"lineNumber": 45,
"ruleDescription": "Emphasis style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md049",
"ruleNames": [
"MD049",
"emphasis-style"
]
},
{ {
"errorContext": null, "errorContext": null,
"errorDetail": "Expected: underscore; Actual: asterisk", "errorDetail": "Expected: underscore; Actual: asterisk",
@ -314,5 +394,85 @@
"MD050", "MD050",
"strong-style" "strong-style"
] ]
},
{
"errorContext": null,
"errorDetail": "Expected: underscore; Actual: asterisk",
"errorRange": [
14,
10
],
"fixInfo": {
"deleteCount": 10,
"editColumn": 14,
"insertText": "__double__"
},
"lineNumber": 47,
"ruleDescription": "Strong style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md050",
"ruleNames": [
"MD050",
"strong-style"
]
},
{
"errorContext": null,
"errorDetail": "Expected: underscore; Actual: asterisk",
"errorRange": [
30,
15
],
"fixInfo": {
"deleteCount": 15,
"editColumn": 30,
"insertText": "__interleaved__"
},
"lineNumber": 47,
"ruleDescription": "Strong style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md050",
"ruleNames": [
"MD050",
"strong-style"
]
},
{
"errorContext": null,
"errorDetail": "Expected: underscore; Actual: asterisk",
"errorRange": [
51,
10
],
"fixInfo": {
"deleteCount": 10,
"editColumn": 51,
"insertText": "__double__"
},
"lineNumber": 47,
"ruleDescription": "Strong style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md050",
"ruleNames": [
"MD050",
"strong-style"
]
},
{
"errorContext": null,
"errorDetail": "Expected: underscore; Actual: asterisk",
"errorRange": [
62,
15
],
"fixInfo": {
"deleteCount": 15,
"editColumn": 62,
"insertText": "__interleaved__"
},
"lineNumber": 47,
"ruleDescription": "Strong style should be consistent",
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md050",
"ruleNames": [
"MD050",
"strong-style"
]
} }
] ]