Update MD022/blanks-around-headings to allow passing -1 for lines_above/lines_below to allow any number of blank lines in that direction (fixes #546).

This commit is contained in:
David Anson 2023-08-06 15:24:35 -07:00
parent f079df140c
commit 809841098d
12 changed files with 273 additions and 58 deletions

View file

@ -4177,25 +4177,33 @@ module.exports = {
var startLine = heading.startLine, var startLine = heading.startLine,
endLine = heading.endLine; endLine = heading.endLine;
var line = lines[startLine - 1].trim(); var line = lines[startLine - 1].trim();
var actualAbove = 0;
for (var i = 0; i < linesAbove; i++) { // Check lines above
if (isBlankLine(lines[startLine - 2 - i])) { if (linesAbove >= 0) {
actualAbove++; var actualAbove = 0;
for (var i = 0; i < linesAbove; i++) {
if (isBlankLine(lines[startLine - 2 - i])) {
actualAbove++;
}
} }
addErrorDetailIf(onError, startLine, linesAbove, actualAbove, "Above", line, null, {
"insertText": getBlockQuote(lines[startLine - 2], linesAbove - actualAbove)
});
} }
addErrorDetailIf(onError, startLine, linesAbove, actualAbove, "Above", line, null, {
"insertText": getBlockQuote(lines[startLine - 2], linesAbove - actualAbove) // Check lines below
}); if (linesBelow >= 0) {
var actualBelow = 0; var actualBelow = 0;
for (var _i = 0; _i < linesBelow; _i++) { for (var _i = 0; _i < linesBelow; _i++) {
if (isBlankLine(lines[endLine + _i])) { if (isBlankLine(lines[endLine + _i])) {
actualBelow++; actualBelow++;
}
} }
addErrorDetailIf(onError, startLine, linesBelow, actualBelow, "Below", line, null, {
"lineNumber": endLine + 1,
"insertText": getBlockQuote(lines[endLine], linesBelow - actualBelow)
});
} }
addErrorDetailIf(onError, startLine, linesBelow, actualBelow, "Below", line, null, {
"lineNumber": endLine + 1,
"insertText": getBlockQuote(lines[endLine], linesBelow - actualBelow)
});
} }
} catch (err) { } catch (err) {
_iterator.e(err); _iterator.e(err);

View file

@ -23,7 +23,9 @@ Some more text
``` ```
The `lines_above` and `lines_below` parameters can be used to specify a The `lines_above` and `lines_below` parameters can be used to specify a
different number of blank lines (including 0) above or below each heading. different number of blank lines (including `0`) above or below each heading. If
the value `-1` is used for either parameter, any number of blank lines is
allowed.
Note: If `lines_above` or `lines_below` are configured to require more than one Note: If `lines_above` or `lines_below` are configured to require more than one
blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. blank line, [MD012/no-multiple-blanks](md012.md) should also be customized.

View file

@ -836,7 +836,9 @@ Some more text
``` ```
The `lines_above` and `lines_below` parameters can be used to specify a The `lines_above` and `lines_below` parameters can be used to specify a
different number of blank lines (including 0) above or below each heading. different number of blank lines (including `0`) above or below each heading. If
the value `-1` is used for either parameter, any number of blank lines is
allowed.
Note: If `lines_above` or `lines_below` are configured to require more than one Note: If `lines_above` or `lines_below` are configured to require more than one
blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. blank line, [MD012/no-multiple-blanks](md012.md) should also be customized.

View file

@ -36,7 +36,9 @@ Some more text
``` ```
The `lines_above` and `lines_below` parameters can be used to specify a The `lines_above` and `lines_below` parameters can be used to specify a
different number of blank lines (including 0) above or below each heading. different number of blank lines (including `0`) above or below each heading. If
the value `-1` is used for either parameter, any number of blank lines is
allowed.
Note: If `lines_above` or `lines_below` are configured to require more than one Note: If `lines_above` or `lines_below` are configured to require more than one
blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. blank line, [MD012/no-multiple-blanks](md012.md) should also be customized.

View file

@ -32,45 +32,53 @@ module.exports = {
for (const heading of headings) { for (const heading of headings) {
const { startLine, endLine } = heading; const { startLine, endLine } = heading;
const line = lines[startLine - 1].trim(); const line = lines[startLine - 1].trim();
let actualAbove = 0;
for (let i = 0; i < linesAbove; i++) { // Check lines above
if (isBlankLine(lines[startLine - 2 - i])) { if (linesAbove >= 0) {
actualAbove++; let actualAbove = 0;
for (let i = 0; i < linesAbove; i++) {
if (isBlankLine(lines[startLine - 2 - i])) {
actualAbove++;
}
} }
addErrorDetailIf(
onError,
startLine,
linesAbove,
actualAbove,
"Above",
line,
null,
{
"insertText":
getBlockQuote(lines[startLine - 2], linesAbove - actualAbove)
}
);
} }
addErrorDetailIf(
onError, // Check lines below
startLine, if (linesBelow >= 0) {
linesAbove, let actualBelow = 0;
actualAbove, for (let i = 0; i < linesBelow; i++) {
"Above", if (isBlankLine(lines[endLine + i])) {
line, actualBelow++;
null, }
{
"insertText":
getBlockQuote(lines[startLine - 2], linesAbove - actualAbove)
}
);
let actualBelow = 0;
for (let i = 0; i < linesBelow; i++) {
if (isBlankLine(lines[endLine + i])) {
actualBelow++;
} }
addErrorDetailIf(
onError,
startLine,
linesBelow,
actualBelow,
"Below",
line,
null,
{
"lineNumber": endLine + 1,
"insertText":
getBlockQuote(lines[endLine], linesBelow - actualBelow)
}
);
} }
addErrorDetailIf(
onError,
startLine,
linesBelow,
actualBelow,
"Below",
line,
null,
{
"lineNumber": endLine + 1,
"insertText":
getBlockQuote(lines[endLine], linesBelow - actualBelow)
}
);
} }
} }
}; };

View file

@ -230,13 +230,13 @@ for (const rule of rules) {
"lines_above": { "lines_above": {
"description": "Blank lines above heading", "description": "Blank lines above heading",
"type": "integer", "type": "integer",
"minimum": 0, "minimum": -1,
"default": 1 "default": 1
}, },
"lines_below": { "lines_below": {
"description": "Blank lines below heading", "description": "Blank lines below heading",
"type": "integer", "type": "integer",
"minimum": 0, "minimum": -1,
"default": 1 "default": 1
} }
}; };

View file

@ -362,13 +362,13 @@
"lines_above": { "lines_above": {
"description": "Blank lines above heading", "description": "Blank lines above heading",
"type": "integer", "type": "integer",
"minimum": 0, "minimum": -1,
"default": 1 "default": 1
}, },
"lines_below": { "lines_below": {
"description": "Blank lines below heading", "description": "Blank lines below heading",
"type": "integer", "type": "integer",
"minimum": 0, "minimum": -1,
"default": 1 "default": 1
} }
}, },

View file

@ -0,0 +1,33 @@
# Blanks Around Headings
## Apple
Text
## Banana
Text
## Cherry
Text
## Durian ##
Text
Elderberry {MD022}
------------------
Text
---
## Fig
<!-- markdownlint-configure-file {
"heading-style": false,
"no-multiple-blanks": false,
"blanks-around-headings": {
"lines_above": -1,
"lines_below": 1
}
} -->

View file

@ -0,0 +1,35 @@
# Blanks Around Headings
## Apple
Text
## Banana
Text
## Cherry
Text
---
## Durian {MD022} ##
Text
---
Elderberry
------------------
Text
## Fig
<!-- markdownlint-configure-file {
"heading-style": false,
"no-multiple-blanks": false,
"blanks-around-headings": {
"lines_above": 1,
"lines_below": -1
}
} -->

View file

@ -919,7 +919,7 @@ test("readme", (t) => new Promise((resolve) => {
})); }));
test("validateJsonUsingConfigSchemaStrict", (t) => { test("validateJsonUsingConfigSchemaStrict", (t) => {
t.plan(156); t.plan(158);
const configRe = const configRe =
/^[\s\S]*<!-- markdownlint-configure-file ([\s\S]*) -->[\s\S]*$/; /^[\s\S]*<!-- markdownlint-configure-file ([\s\S]*) -->[\s\S]*$/;
const ignoreFiles = new Set([ const ignoreFiles = new Set([

View file

@ -4173,6 +4173,68 @@ Generated by [AVA](https://avajs.dev).
`, `,
} }
## blanks-around-headings--1-1.md
> Snapshot 1
{
errors: [
{
errorContext: 'Elderberry {MD022}',
errorDetail: 'Expected: 1; Actual: 0; Below',
errorRange: null,
fixInfo: {
insertText: `␊
`,
lineNumber: 21,
},
lineNumber: 19,
ruleDescription: 'Headings should be surrounded by blank lines',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md022.md',
ruleNames: [
'MD022',
'blanks-around-headings',
'blanks-around-headers',
],
},
],
fixed: `# Blanks Around Headings␊
## Apple␊
Text␊
## Banana␊
Text␊
## Cherry␊
Text␊
## Durian ##␊
Text␊
Elderberry {MD022}␊
------------------␊
Text␊
---␊
## Fig␊
<!-- markdownlint-configure-file {␊
"heading-style": false,␊
"no-multiple-blanks": false,␊
"blanks-around-headings": {␊
"lines_above": -1,␊
"lines_below": 1␊
}␊
} -->␊
`,
}
## blanks-around-headings-0-2.md ## blanks-around-headings-0-2.md
> Snapshot 1 > Snapshot 1
@ -4256,6 +4318,69 @@ Generated by [AVA](https://avajs.dev).
`, `,
} }
## blanks-around-headings-1--1.md
> Snapshot 1
{
errors: [
{
errorContext: '## Durian {MD022} ##',
errorDetail: 'Expected: 1; Actual: 0; Above',
errorRange: null,
fixInfo: {
insertText: `␊
`,
},
lineNumber: 16,
ruleDescription: 'Headings should be surrounded by blank lines',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md022.md',
ruleNames: [
'MD022',
'blanks-around-headings',
'blanks-around-headers',
],
},
],
fixed: `# Blanks Around Headings␊
## Apple␊
Text␊
## Banana␊
Text␊
## Cherry␊
Text␊
---␊
## Durian {MD022} ##␊
Text␊
---␊
Elderberry␊
------------------␊
Text␊
## Fig␊
<!-- markdownlint-configure-file {␊
"heading-style": false,␊
"no-multiple-blanks": false,␊
"blanks-around-headings": {␊
"lines_above": 1,␊
"lines_below": -1␊
}␊
} -->␊
`,
}
## blanks-around-headings-3-0.md ## blanks-around-headings-3-0.md
> Snapshot 1 > Snapshot 1