Update MD043/required-headings to add match_case parameter (fixes #613).

This commit is contained in:
Mateus Ferreira 2022-10-22 03:15:50 -04:00 committed by GitHub
parent 592a42b0cb
commit 37f74ee958
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 125 additions and 6 deletions

View file

@ -4297,6 +4297,7 @@ module.exports = {
"tags": ["headings", "headers"],
"function": function MD043(params, onError) {
const requiredHeadings = params.config.headings || params.config.headers;
const matchCase = params.config.match_case || false;
if (Array.isArray(requiredHeadings)) {
const levels = {};
for (const level of [1, 2, 3, 4, 5, 6]) {
@ -4307,6 +4308,7 @@ module.exports = {
let hasError = false;
let anyHeadings = false;
const getExpected = () => requiredHeadings[i++] || "[None]";
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
forEachHeading(params, (heading, content) => {
if (!hasError) {
anyHeadings = true;
@ -4314,7 +4316,7 @@ module.exports = {
const expected = getExpected();
if (expected === "*") {
const nextExpected = getExpected();
if (nextExpected.toLowerCase() !== actual.toLowerCase()) {
if (handleCase(nextExpected) !== handleCase(actual)) {
matchAny = true;
i--;
}
@ -4322,7 +4324,7 @@ module.exports = {
else if (expected === "+") {
matchAny = true;
}
else if (expected.toLowerCase() === actual.toLowerCase()) {
else if (handleCase(expected) === handleCase(actual)) {
matchAny = false;
}
else if (matchAny) {

View file

@ -1696,7 +1696,7 @@ Tags: headings, headers
Aliases: required-headings, required-headers
Parameters: headings, headers (array of string; default `null` for disabled)
Parameters: headings, headers, match_case (array of string; default `null` for disabled, boolean; default false)
> If `headings` is not provided, `headers` (deprecated) will be used.
@ -1752,6 +1752,10 @@ problematic heading (otherwise, it outputs the last line number of the file).
Note that while the `headings` parameter uses the "## Text" ATX heading style for
simplicity, a file may use any supported heading style.
By default, the case of headings in the document is not required to match that of
`headings`. To require that case match exactly, set the `match_case` parameter to
`true`.
Rationale: Projects may wish to enforce a consistent document structure across
a set of similar content.

View file

@ -11,6 +11,7 @@ module.exports = {
"tags": [ "headings", "headers" ],
"function": function MD043(params, onError) {
const requiredHeadings = params.config.headings || params.config.headers;
const matchCase = params.config.match_case || false;
if (Array.isArray(requiredHeadings)) {
const levels = {};
for (const level of [ 1, 2, 3, 4, 5, 6 ]) {
@ -21,6 +22,7 @@ module.exports = {
let hasError = false;
let anyHeadings = false;
const getExpected = () => requiredHeadings[i++] || "[None]";
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
forEachHeading(params, (heading, content) => {
if (!hasError) {
anyHeadings = true;
@ -28,13 +30,13 @@ module.exports = {
const expected = getExpected();
if (expected === "*") {
const nextExpected = getExpected();
if (nextExpected.toLowerCase() !== actual.toLowerCase()) {
if (handleCase(nextExpected) !== handleCase(actual)) {
matchAny = true;
i--;
}
} else if (expected === "+") {
matchAny = true;
} else if (expected.toLowerCase() === actual.toLowerCase()) {
} else if (handleCase(expected) === handleCase(actual)) {
matchAny = false;
} else if (matchAny) {
i--;

View file

@ -228,7 +228,9 @@
// List of headings
"headings": [],
// List of headings
"headers": []
"headers": [],
// Match case of headings
"match_case": false
},
// MD044/proper-names - Proper names should have the correct capitalization

View file

@ -208,6 +208,8 @@ MD043:
headings: []
# List of headings
headers: []
# Match case of headings
match_case: false
# MD044/proper-names - Proper names should have the correct capitalization
MD044:

View file

@ -395,6 +395,11 @@ for (const rule of rules) {
"pattern": "^(\\*|\\+|#{1,6} .*)$"
},
"default": []
},
"match_case": {
"description": "Match case of headings",
"type": "boolean",
"default": false
}
};
break;

View file

@ -751,6 +751,11 @@
"pattern": "^(\\*|\\+|#{1,6} .*)$"
},
"default": []
},
"match_case": {
"description": "Match case of headings",
"type": "boolean",
"default": false
}
},
"additionalProperties": false

View file

@ -0,0 +1,12 @@
{
"MD043": {
"headings": [
"# Title",
"## First Heading",
"## Second Heading",
"*",
"## Third Heading"
],
"match_case": true
}
}

View file

@ -0,0 +1,9 @@
# Title
## First Heading
## Second Heading
### Random heading
## Third Heading

View file

@ -0,0 +1,12 @@
{
"MD043": {
"headings": [
"# Title",
"## First Heading",
"## Second Heading",
"*",
"## Third Heading"
],
"match_case": true
}
}

View file

@ -0,0 +1,11 @@
# Title
## First Heading
## SECOND HEADING
{MD043:5}
### Random heading
## Third Heading

View file

@ -34838,6 +34838,24 @@ Generated by [AVA](https://avajs.dev).
`,
}
## required-headings-match-case.md
> Snapshot 1
{
errors: [],
fixed: `# Title␊
## First Heading␊
## Second Heading␊
### Random heading␊
## Third Heading␊
`,
}
## required-headings-missing-first.md
> Snapshot 1
@ -35216,6 +35234,41 @@ Generated by [AVA](https://avajs.dev).
`,
}
## required-headings-wrong-match-case.md
> Snapshot 1
{
errors: [
{
errorContext: null,
errorDetail: 'Expected: ## Second Heading; Actual: ## SECOND HEADING',
errorRange: null,
fixInfo: null,
lineNumber: 5,
ruleDescription: 'Required heading structure',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md043',
ruleNames: [
'MD043',
'required-headings',
'required-headers',
],
},
],
fixed: `# Title␊
## First Heading␊
## SECOND HEADING␊
{MD043:5}␊
### Random heading␊
## Third Heading␊
`,
}
## required-headings-zero-or-more-last.md
> Snapshot 1