Reimplement MD005/list-indent using micromark tokens, improve range reporting.

This commit is contained in:
David Anson 2023-10-12 21:43:31 -07:00
parent bfb484b513
commit 9297bcde1c
5 changed files with 271 additions and 77 deletions

View file

@ -3400,44 +3400,42 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"), var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
addError = _require.addError, addError = _require.addError,
addErrorDetailIf = _require.addErrorDetailIf, addErrorDetailIf = _require.addErrorDetailIf;
indentFor = _require.indentFor, var _require2 = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs"),
listItemMarkerRe = _require.listItemMarkerRe, filterByTypes = _require2.filterByTypes;
orderedListItemMarkerRe = _require.orderedListItemMarkerRe,
rangeFromRegExp = _require.rangeFromRegExp;
var _require2 = __webpack_require__(/*! ./cache */ "../lib/cache.js"),
flattenedLists = _require2.flattenedLists;
module.exports = { module.exports = {
"names": ["MD005", "list-indent"], "names": ["MD005", "list-indent"],
"description": "Inconsistent indentation for list items at the same level", "description": "Inconsistent indentation for list items at the same level",
"tags": ["bullet", "ul", "indentation"], "tags": ["bullet", "ul", "indentation"],
"function": function MD005(params, onError) { "function": function MD005(params, onError) {
var _iterator = _createForOfIteratorHelper(flattenedLists()), var lists = filterByTypes(params.parsers.micromark.tokens, ["listOrdered", "listUnordered"]);
var _iterator = _createForOfIteratorHelper(lists),
_step; _step;
try { try {
for (_iterator.s(); !(_step = _iterator.n()).done;) { for (_iterator.s(); !(_step = _iterator.n()).done;) {
var list = _step.value; var list = _step.value;
var expectedIndent = list.indent; var expectedIndent = list.startColumn - 1;
var expectedEnd = 0; var expectedEnd = 0;
var actualEnd = -1;
var endMatching = false; var endMatching = false;
var _iterator2 = _createForOfIteratorHelper(list.items), var listItemPrefixes = list.children.filter(function (token) {
return token.type === "listItemPrefix";
});
var _iterator2 = _createForOfIteratorHelper(listItemPrefixes),
_step2; _step2;
try { try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var item = _step2.value; var listItemPrefix = _step2.value;
var line = item.line, var lineNumber = listItemPrefix.startLine;
lineNumber = item.lineNumber; var actualIndent = listItemPrefix.startColumn - 1;
var actualIndent = indentFor(item); var markerLength = listItemPrefix.text.trim().length;
var match = null; var range = [1, listItemPrefix.startColumn + markerLength];
if (list.unordered) { if (list.type === "listUnordered") {
addErrorDetailIf(onError, lineNumber, expectedIndent, actualIndent, null, null, rangeFromRegExp(line, listItemMarkerRe) addErrorDetailIf(onError, lineNumber, expectedIndent, actualIndent, null, null, range
// No fixInfo; MD007 handles this scenario better // No fixInfo; MD007 handles this scenario better
); );
} else if (match = orderedListItemMarkerRe.exec(line)) { } else {
actualEnd = match[0].length; var actualEnd = range[1] - 1;
expectedEnd = expectedEnd || actualEnd; expectedEnd = expectedEnd || actualEnd;
var markerLength = match[1].length + 1;
if (expectedIndent !== actualIndent || endMatching) { if (expectedIndent !== actualIndent || endMatching) {
if (expectedEnd === actualEnd) { if (expectedEnd === actualEnd) {
endMatching = true; endMatching = true;
@ -3445,7 +3443,7 @@ module.exports = {
var detail = endMatching ? "Expected: (".concat(expectedEnd, "); Actual: (").concat(actualEnd, ")") : "Expected: ".concat(expectedIndent, "; Actual: ").concat(actualIndent); var detail = endMatching ? "Expected: (".concat(expectedEnd, "); Actual: (").concat(actualEnd, ")") : "Expected: ".concat(expectedIndent, "; Actual: ").concat(actualIndent);
var expected = endMatching ? expectedEnd - markerLength : expectedIndent; var expected = endMatching ? expectedEnd - markerLength : expectedIndent;
var actual = endMatching ? actualEnd - markerLength : actualIndent; var actual = endMatching ? actualEnd - markerLength : actualIndent;
addError(onError, lineNumber, detail, null, rangeFromRegExp(line, listItemMarkerRe), { addError(onError, lineNumber, detail, undefined, range, {
"editColumn": Math.min(actual, expected) + 1, "editColumn": Math.min(actual, expected) + 1,
"deleteCount": Math.max(actual - expected, 0), "deleteCount": Math.max(actual - expected, 0),
"insertText": "".padEnd(Math.max(expected - actual, 0)) "insertText": "".padEnd(Math.max(expected - actual, 0))

View file

@ -2,25 +2,30 @@
"use strict"; "use strict";
const { addError, addErrorDetailIf, indentFor, listItemMarkerRe, const { addError, addErrorDetailIf } = require("../helpers");
orderedListItemMarkerRe, rangeFromRegExp } = require("../helpers"); const { filterByTypes } = require("../helpers/micromark.cjs");
const { flattenedLists } = require("./cache");
module.exports = { module.exports = {
"names": [ "MD005", "list-indent" ], "names": [ "MD005", "list-indent" ],
"description": "Inconsistent indentation for list items at the same level", "description": "Inconsistent indentation for list items at the same level",
"tags": [ "bullet", "ul", "indentation" ], "tags": [ "bullet", "ul", "indentation" ],
"function": function MD005(params, onError) { "function": function MD005(params, onError) {
for (const list of flattenedLists()) { const lists = filterByTypes(
const expectedIndent = list.indent; params.parsers.micromark.tokens,
[ "listOrdered", "listUnordered" ]
);
for (const list of lists) {
const expectedIndent = list.startColumn - 1;
let expectedEnd = 0; let expectedEnd = 0;
let actualEnd = -1;
let endMatching = false; let endMatching = false;
for (const item of list.items) { const listItemPrefixes =
const { line, lineNumber } = item; list.children.filter((token) => (token.type === "listItemPrefix"));
const actualIndent = indentFor(item); for (const listItemPrefix of listItemPrefixes) {
let match = null; const lineNumber = listItemPrefix.startLine;
if (list.unordered) { const actualIndent = listItemPrefix.startColumn - 1;
const markerLength = listItemPrefix.text.trim().length;
const range = [ 1, listItemPrefix.startColumn + markerLength ];
if (list.type === "listUnordered") {
addErrorDetailIf( addErrorDetailIf(
onError, onError,
lineNumber, lineNumber,
@ -28,13 +33,12 @@ module.exports = {
actualIndent, actualIndent,
null, null,
null, null,
rangeFromRegExp(line, listItemMarkerRe) range
// No fixInfo; MD007 handles this scenario better // No fixInfo; MD007 handles this scenario better
); );
} else if ((match = orderedListItemMarkerRe.exec(line))) { } else {
actualEnd = match[0].length; const actualEnd = range[1] - 1;
expectedEnd = expectedEnd || actualEnd; expectedEnd = expectedEnd || actualEnd;
const markerLength = match[1].length + 1;
if ((expectedIndent !== actualIndent) || endMatching) { if ((expectedIndent !== actualIndent) || endMatching) {
if (expectedEnd === actualEnd) { if (expectedEnd === actualEnd) {
endMatching = true; endMatching = true;
@ -52,8 +56,8 @@ module.exports = {
onError, onError,
lineNumber, lineNumber,
detail, detail,
null, undefined,
rangeFromRegExp(line, listItemMarkerRe), range,
{ {
"editColumn": Math.min(actual, expected) + 1, "editColumn": Math.min(actual, expected) + 1,
"deleteCount": Math.max(actual - expected, 0), "deleteCount": Math.max(actual - expected, 0),

View file

@ -83,37 +83,37 @@ Text
> Text > Text
> >
> > - Item {MD004} > > - Item {MD004}
> > - Item {MD004} {MD027} > > - Item {MD004} {MD005} {MD027}
> > - Item {MD004} > > - Item {MD004} {MD005}
> > > >
> > > - Item {MD004} > > > - Item {MD004}
> > > - Item {MD004} {MD027} > > > - Item {MD004} {MD005} {MD027}
> > > - Item {MD004} {MD027} > > > - Item {MD004} {MD005} {MD027}
Text Text
> Text > Text
> > - Item {MD004} {MD032} > > - Item {MD004} {MD032}
> > - Item {MD004} {MD027} > > - Item {MD004} {MD005} {MD027}
> > - Item {MD004} {MD032} > > - Item {MD004} {MD005} {MD032}
> > > - Item {MD004} {MD032} > > > - Item {MD004} {MD032}
> > > - Item {MD004} {MD027} > > > - Item {MD004} {MD005} {MD027}
> > > - Item {MD004} {MD027} > > > - Item {MD004} {MD005} {MD027}
Text Text
>+ Item >+ Item
> + Item > + Item {MD005}
>> >>
>>+ Item >>+ Item
>> + Item >> + Item {MD005}
Text Text
>+ Item >+ Item
> + Item {MD032} > + Item {MD005} {MD032}
>>+ Item {MD032} >>+ Item {MD032}
>> + Item >> + Item {MD005}
Text Text

View file

@ -28764,7 +28764,7 @@ Generated by [AVA](https://avajs.dev).
}, },
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 2; Actual: 3', errorDetail: 'Expected: 7; Actual: 8',
errorRange: [ errorRange: [
1, 1,
10, 10,
@ -28780,7 +28780,7 @@ Generated by [AVA](https://avajs.dev).
}, },
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 0; Actual: 1', errorDetail: 'Expected: 5; Actual: 6',
errorRange: [ errorRange: [
1, 1,
8, 8,
@ -28796,7 +28796,7 @@ Generated by [AVA](https://avajs.dev).
}, },
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 4; Actual: 5', errorDetail: 'Expected: 9; Actual: 10',
errorRange: [ errorRange: [
1, 1,
12, 12,
@ -28812,7 +28812,7 @@ Generated by [AVA](https://avajs.dev).
}, },
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 2; Actual: 3', errorDetail: 'Expected: 8; Actual: 9',
errorRange: [ errorRange: [
1, 1,
11, 11,
@ -28828,7 +28828,199 @@ Generated by [AVA](https://avajs.dev).
}, },
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 0; Actual: 1', errorDetail: 'Expected: 6; Actual: 7',
errorRange: [
1,
9,
],
fixInfo: null,
lineNumber: 86,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 6; Actual: 7',
errorRange: [
1,
9,
],
fixInfo: null,
lineNumber: 87,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 8; Actual: 9',
errorRange: [
1,
11,
],
fixInfo: null,
lineNumber: 90,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 8; Actual: 9',
errorRange: [
1,
11,
],
fixInfo: null,
lineNumber: 91,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 6; Actual: 7',
errorRange: [
1,
9,
],
fixInfo: null,
lineNumber: 97,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 6; Actual: 7',
errorRange: [
1,
9,
],
fixInfo: null,
lineNumber: 98,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 8; Actual: 9',
errorRange: [
1,
11,
],
fixInfo: null,
lineNumber: 100,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 8; Actual: 9',
errorRange: [
1,
11,
],
fixInfo: null,
lineNumber: 101,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 1; Actual: 2',
errorRange: [
1,
4,
],
fixInfo: null,
lineNumber: 106,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 2; Actual: 3',
errorRange: [
1,
5,
],
fixInfo: null,
lineNumber: 109,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 1; Actual: 2',
errorRange: [
1,
4,
],
fixInfo: null,
lineNumber: 114,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 2; Actual: 3',
errorRange: [
1,
5,
],
fixInfo: null,
lineNumber: 116,
ruleDescription: 'Inconsistent indentation for list items at the same level',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md005.md',
ruleNames: [
'MD005',
'list-indent',
],
},
{
errorContext: null,
errorDetail: 'Expected: 4; Actual: 5',
errorRange: [ errorRange: [
1, 1,
7, 7,
@ -28844,7 +29036,7 @@ Generated by [AVA](https://avajs.dev).
}, },
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 2; Actual: 3', errorDetail: 'Expected: 6; Actual: 7',
errorRange: [ errorRange: [
1, 1,
9, 9,
@ -28979,7 +29171,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: ' > > - Item {MD004} {MD027}', errorContext: ' > > - Item {MD004} {MD005} ...',
errorDetail: null, errorDetail: null,
errorRange: [ errorRange: [
1, 1,
@ -28998,7 +29190,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: ' > > > - Item {MD004} {MD027...', errorContext: ' > > > - Item {MD004} {MD005...',
errorDetail: null, errorDetail: null,
errorRange: [ errorRange: [
1, 1,
@ -29017,7 +29209,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: ' > > > - Item {MD004} {MD027...', errorContext: ' > > > - Item {MD004} {MD005...',
errorDetail: null, errorDetail: null,
errorRange: [ errorRange: [
1, 1,
@ -29036,7 +29228,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: ' > > - Item {MD004} {MD027}', errorContext: ' > > - Item {MD004} {MD005} ...',
errorDetail: null, errorDetail: null,
errorRange: [ errorRange: [
1, 1,
@ -29055,7 +29247,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: ' > > > - Item {MD004} {MD027...', errorContext: ' > > > - Item {MD004} {MD005...',
errorDetail: null, errorDetail: null,
errorRange: [ errorRange: [
1, 1,
@ -29074,7 +29266,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: ' > > > - Item {MD004} {MD027...', errorContext: ' > > > - Item {MD004} {MD005...',
errorDetail: null, errorDetail: null,
errorRange: [ errorRange: [
1, 1,
@ -29242,7 +29434,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: '> > - Item {MD004} {MD032}', errorContext: '> > - Item {MD004} {MD005} {MD...',
errorDetail: null, errorDetail: null,
errorRange: null, errorRange: null,
fixInfo: { fixInfo: {
@ -29275,7 +29467,7 @@ Generated by [AVA](https://avajs.dev).
], ],
}, },
{ {
errorContext: '> + Item {MD032}', errorContext: '> + Item {MD005} {MD032}',
errorDetail: null, errorDetail: null,
errorRange: null, errorRange: null,
fixInfo: { fixInfo: {
@ -29395,40 +29587,40 @@ Generated by [AVA](https://avajs.dev).
> Text␊ > Text␊
>␊ >␊
> > + Item {MD004}␊ > > + Item {MD004}␊
> > + Item {MD004} {MD027}␊ > > + Item {MD004} {MD005} {MD027}␊
> > + Item {MD004}␊ > > + Item {MD004} {MD005}
> >␊ > >␊
> > > + Item {MD004}␊ > > > + Item {MD004}␊
> > > + Item {MD004} {MD027}␊ > > > + Item {MD004} {MD005} {MD027}␊
> > > + Item {MD004} {MD027}␊ > > > + Item {MD004} {MD005} {MD027}␊
Text␊ Text␊
> Text␊ > Text␊
> >␊ > >␊
> > + Item {MD004} {MD032}␊ > > + Item {MD004} {MD032}␊
> > + Item {MD004} {MD027}␊ > > + Item {MD004} {MD005} {MD027}␊
> > + Item {MD004} {MD032}␊ > > + Item {MD004} {MD005} {MD032}␊
> > >␊ > > >␊
> > > + Item {MD004} {MD032}␊ > > > + Item {MD004} {MD032}␊
> > > + Item {MD004} {MD027}␊ > > > + Item {MD004} {MD005} {MD027}␊
> > > + Item {MD004} {MD027}␊ > > > + Item {MD004} {MD005} {MD027}␊
Text␊ Text␊
>+ Item␊ >+ Item␊
> + Item␊ > + Item {MD005}
>>␊ >>␊
>>+ Item␊ >>+ Item␊
>> + Item␊ >> + Item {MD005}
Text␊ Text␊
>+ Item␊ >+ Item␊
> + Item {MD032}␊ > + Item {MD005} {MD032}␊
>>␊ >>␊
>>+ Item {MD032}␊ >>+ Item {MD032}␊
>> + Item␊ >> + Item {MD005}
Text␊ Text␊