Update MD018/MD019/MD020/MD021 to report fixInfo for violations.

This commit is contained in:
David Anson 2019-09-08 16:51:00 -07:00
parent c8a74bd72c
commit 316bfeadaa
8 changed files with 167 additions and 50 deletions

View file

@ -2,8 +2,7 @@
"use strict";
const { addErrorContext, atxHeadingSpaceRe, forEachLine,
rangeFromRegExp } = require("../helpers");
const { addErrorContext, forEachLine } = require("../helpers");
const { lineMetadata } = require("./cache");
module.exports = {
@ -12,9 +11,20 @@ module.exports = {
"tags": [ "headings", "headers", "atx", "spaces" ],
"function": function MD018(params, onError) {
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
if (!inCode && /^#+[^#\s]/.test(line) && !/#$/.test(line)) {
addErrorContext(onError, lineIndex + 1, line.trim(), null,
null, rangeFromRegExp(line, atxHeadingSpaceRe));
if (!inCode && /^#+[^#\s]/.test(line) && !/#\s*$/.test(line)) {
const hashCount = /^#+/.exec(line)[0].length;
addErrorContext(
onError,
lineIndex + 1,
line.trim(),
null,
null,
[ 1, hashCount + 1 ],
{
"editColumn": hashCount + 1,
"insertText": " "
}
);
}
});
}

View file

@ -2,20 +2,37 @@
"use strict";
const { addErrorContext, atxHeadingSpaceRe, filterTokens, headingStyleFor,
rangeFromRegExp } = require("../helpers");
const { addErrorContext, filterTokens, headingStyleFor } =
require("../helpers");
module.exports = {
"names": [ "MD019", "no-multiple-space-atx" ],
"description": "Multiple spaces after hash on atx style heading",
"tags": [ "headings", "headers", "atx", "spaces" ],
"function": function MD019(params, onError) {
filterTokens(params, "heading_open", function forToken(token) {
if ((headingStyleFor(token) === "atx") &&
/^#+\s\s/.test(token.line)) {
addErrorContext(onError, token.lineNumber, token.line.trim(),
null, null,
rangeFromRegExp(token.line, atxHeadingSpaceRe));
filterTokens(params, "heading_open", (token) => {
if (headingStyleFor(token) === "atx") {
const { line, lineNumber } = token;
const match = /^(#+)(\s{2,})/.exec(line);
if (match) {
const [
,
{ "length": hashLength },
{ "length": spacesLength }
] = match;
addErrorContext(
onError,
lineNumber,
line.trim(),
null,
null,
[ 1, hashLength + spacesLength + 1 ],
{
"editColumn": hashLength + 1,
"deleteCount": spacesLength - 1
}
);
}
}
});
}

View file

@ -2,23 +2,59 @@
"use strict";
const { addErrorContext, forEachLine, rangeFromRegExp } = require("../helpers");
const { addErrorContext, forEachLine } = require("../helpers");
const { lineMetadata } = require("./cache");
const atxClosedHeadingNoSpaceRe = /(?:^#+[^#\s])|(?:[^#\s]#+\s*$)/;
module.exports = {
"names": [ "MD020", "no-missing-space-closed-atx" ],
"description": "No space inside hashes on closed atx style heading",
"tags": [ "headings", "headers", "atx_closed", "spaces" ],
"function": function MD020(params, onError) {
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
if (!inCode && /^#+[^#]*[^\\]#+$/.test(line)) {
const left = /^#+[^#\s]/.test(line);
const right = /[^#\s]#+$/.test(line);
if (left || right) {
addErrorContext(onError, lineIndex + 1, line.trim(), left,
right, rangeFromRegExp(line, atxClosedHeadingNoSpaceRe));
if (!inCode) {
const match = /^(#+)(\s*)([^#]+?)(\s*)(\\?)(#+)(\s*)$/.exec(line);
if (match) {
const [
,
leftHash,
{ "length": leftSpaceLength },
content,
{ "length": rightSpaceLength },
rightEscape,
rightHash,
{ "length": trailSpaceLength }
] = match;
const leftHashLength = leftHash.length;
const rightHashLength = rightHash.length;
const left = !leftSpaceLength;
const right =
(!rightSpaceLength && (!rightEscape || (rightHashLength > 1))) ||
(rightEscape && (rightHashLength > 1));
if (left || right) {
const range = left ?
[
1,
leftHashLength + 1
] :
[
line.length - trailSpaceLength - rightHashLength,
rightHashLength + 1
];
addErrorContext(
onError,
lineIndex + 1,
line.trim(),
left,
right,
range,
{
"editColumn": 1,
"deleteLength": line.length,
"insertText":
`${leftHash} ${content} ${rightEscape}${rightHash}`
}
);
}
}
}
});

View file

@ -2,24 +2,57 @@
"use strict";
const { addErrorContext, filterTokens, headingStyleFor, rangeFromRegExp } =
const { addErrorContext, filterTokens, headingStyleFor } =
require("../helpers");
const atxClosedHeadingSpaceRe = /(?:^#+\s\s+?\S)|(?:\S\s\s+?#+\s*$)/;
module.exports = {
"names": [ "MD021", "no-multiple-space-closed-atx" ],
"description": "Multiple spaces inside hashes on closed atx style heading",
"tags": [ "headings", "headers", "atx_closed", "spaces" ],
"function": function MD021(params, onError) {
filterTokens(params, "heading_open", function forToken(token) {
filterTokens(params, "heading_open", (token) => {
if (headingStyleFor(token) === "atx_closed") {
const left = /^#+\s\s/.test(token.line);
const right = /\s\s#+$/.test(token.line);
if (left || right) {
addErrorContext(onError, token.lineNumber, token.line.trim(),
left, right,
rangeFromRegExp(token.line, atxClosedHeadingSpaceRe));
const { line, lineNumber } = token;
const match = /^(#+)(\s+)([^#]+?)(\s+)(#+)(\s*)$/.exec(line);
if (match) {
const [
,
leftHash,
{ "length": leftSpaceLength },
content,
{ "length": rightSpaceLength },
rightHash,
{ "length": trailSpaceLength }
] = match;
const left = leftSpaceLength > 1;
const right = rightSpaceLength > 1;
if (left || right) {
const length = line.length;
const leftHashLength = leftHash.length;
const rightHashLength = rightHash.length;
const range = left ?
[
1,
leftHashLength + leftSpaceLength + 1
] :
[
length - trailSpaceLength - rightHashLength - rightSpaceLength,
rightSpaceLength + rightHashLength + 1
];
addErrorContext(
onError,
lineNumber,
line.trim(),
left,
right,
range,
{
"editColumn": 1,
"deleteLength": length,
"insertText": `${leftHash} ${content} ${rightHash}`
}
);
}
}
}
});