mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Update MD043/required-headings to add match_case parameter (fixes #613).
This commit is contained in:
parent
592a42b0cb
commit
37f74ee958
13 changed files with 125 additions and 6 deletions
|
|
@ -4297,6 +4297,7 @@ module.exports = {
|
||||||
"tags": ["headings", "headers"],
|
"tags": ["headings", "headers"],
|
||||||
"function": function MD043(params, onError) {
|
"function": function MD043(params, onError) {
|
||||||
const requiredHeadings = params.config.headings || params.config.headers;
|
const requiredHeadings = params.config.headings || params.config.headers;
|
||||||
|
const matchCase = params.config.match_case || false;
|
||||||
if (Array.isArray(requiredHeadings)) {
|
if (Array.isArray(requiredHeadings)) {
|
||||||
const levels = {};
|
const levels = {};
|
||||||
for (const level of [1, 2, 3, 4, 5, 6]) {
|
for (const level of [1, 2, 3, 4, 5, 6]) {
|
||||||
|
|
@ -4307,6 +4308,7 @@ module.exports = {
|
||||||
let hasError = false;
|
let hasError = false;
|
||||||
let anyHeadings = false;
|
let anyHeadings = false;
|
||||||
const getExpected = () => requiredHeadings[i++] || "[None]";
|
const getExpected = () => requiredHeadings[i++] || "[None]";
|
||||||
|
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
|
||||||
forEachHeading(params, (heading, content) => {
|
forEachHeading(params, (heading, content) => {
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
anyHeadings = true;
|
anyHeadings = true;
|
||||||
|
|
@ -4314,7 +4316,7 @@ module.exports = {
|
||||||
const expected = getExpected();
|
const expected = getExpected();
|
||||||
if (expected === "*") {
|
if (expected === "*") {
|
||||||
const nextExpected = getExpected();
|
const nextExpected = getExpected();
|
||||||
if (nextExpected.toLowerCase() !== actual.toLowerCase()) {
|
if (handleCase(nextExpected) !== handleCase(actual)) {
|
||||||
matchAny = true;
|
matchAny = true;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
@ -4322,7 +4324,7 @@ module.exports = {
|
||||||
else if (expected === "+") {
|
else if (expected === "+") {
|
||||||
matchAny = true;
|
matchAny = true;
|
||||||
}
|
}
|
||||||
else if (expected.toLowerCase() === actual.toLowerCase()) {
|
else if (handleCase(expected) === handleCase(actual)) {
|
||||||
matchAny = false;
|
matchAny = false;
|
||||||
}
|
}
|
||||||
else if (matchAny) {
|
else if (matchAny) {
|
||||||
|
|
|
||||||
|
|
@ -1696,7 +1696,7 @@ Tags: headings, headers
|
||||||
|
|
||||||
Aliases: required-headings, required-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.
|
> 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
|
Note that while the `headings` parameter uses the "## Text" ATX heading style for
|
||||||
simplicity, a file may use any supported heading style.
|
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
|
Rationale: Projects may wish to enforce a consistent document structure across
|
||||||
a set of similar content.
|
a set of similar content.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ module.exports = {
|
||||||
"tags": [ "headings", "headers" ],
|
"tags": [ "headings", "headers" ],
|
||||||
"function": function MD043(params, onError) {
|
"function": function MD043(params, onError) {
|
||||||
const requiredHeadings = params.config.headings || params.config.headers;
|
const requiredHeadings = params.config.headings || params.config.headers;
|
||||||
|
const matchCase = params.config.match_case || false;
|
||||||
if (Array.isArray(requiredHeadings)) {
|
if (Array.isArray(requiredHeadings)) {
|
||||||
const levels = {};
|
const levels = {};
|
||||||
for (const level of [ 1, 2, 3, 4, 5, 6 ]) {
|
for (const level of [ 1, 2, 3, 4, 5, 6 ]) {
|
||||||
|
|
@ -21,6 +22,7 @@ module.exports = {
|
||||||
let hasError = false;
|
let hasError = false;
|
||||||
let anyHeadings = false;
|
let anyHeadings = false;
|
||||||
const getExpected = () => requiredHeadings[i++] || "[None]";
|
const getExpected = () => requiredHeadings[i++] || "[None]";
|
||||||
|
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
|
||||||
forEachHeading(params, (heading, content) => {
|
forEachHeading(params, (heading, content) => {
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
anyHeadings = true;
|
anyHeadings = true;
|
||||||
|
|
@ -28,13 +30,13 @@ module.exports = {
|
||||||
const expected = getExpected();
|
const expected = getExpected();
|
||||||
if (expected === "*") {
|
if (expected === "*") {
|
||||||
const nextExpected = getExpected();
|
const nextExpected = getExpected();
|
||||||
if (nextExpected.toLowerCase() !== actual.toLowerCase()) {
|
if (handleCase(nextExpected) !== handleCase(actual)) {
|
||||||
matchAny = true;
|
matchAny = true;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
} else if (expected === "+") {
|
} else if (expected === "+") {
|
||||||
matchAny = true;
|
matchAny = true;
|
||||||
} else if (expected.toLowerCase() === actual.toLowerCase()) {
|
} else if (handleCase(expected) === handleCase(actual)) {
|
||||||
matchAny = false;
|
matchAny = false;
|
||||||
} else if (matchAny) {
|
} else if (matchAny) {
|
||||||
i--;
|
i--;
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,9 @@
|
||||||
// List of headings
|
// List of headings
|
||||||
"headings": [],
|
"headings": [],
|
||||||
// List of headings
|
// List of headings
|
||||||
"headers": []
|
"headers": [],
|
||||||
|
// Match case of headings
|
||||||
|
"match_case": false
|
||||||
},
|
},
|
||||||
|
|
||||||
// MD044/proper-names - Proper names should have the correct capitalization
|
// MD044/proper-names - Proper names should have the correct capitalization
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,8 @@ MD043:
|
||||||
headings: []
|
headings: []
|
||||||
# List of headings
|
# List of headings
|
||||||
headers: []
|
headers: []
|
||||||
|
# Match case of headings
|
||||||
|
match_case: false
|
||||||
|
|
||||||
# MD044/proper-names - Proper names should have the correct capitalization
|
# MD044/proper-names - Proper names should have the correct capitalization
|
||||||
MD044:
|
MD044:
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,11 @@ for (const rule of rules) {
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
|
},
|
||||||
|
"match_case": {
|
||||||
|
"description": "Match case of headings",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -751,6 +751,11 @@
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
|
},
|
||||||
|
"match_case": {
|
||||||
|
"description": "Match case of headings",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
|
||||||
12
test/required-headings-match-case.json
Normal file
12
test/required-headings-match-case.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"MD043": {
|
||||||
|
"headings": [
|
||||||
|
"# Title",
|
||||||
|
"## First Heading",
|
||||||
|
"## Second Heading",
|
||||||
|
"*",
|
||||||
|
"## Third Heading"
|
||||||
|
],
|
||||||
|
"match_case": true
|
||||||
|
}
|
||||||
|
}
|
||||||
9
test/required-headings-match-case.md
Normal file
9
test/required-headings-match-case.md
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Title
|
||||||
|
|
||||||
|
## First Heading
|
||||||
|
|
||||||
|
## Second Heading
|
||||||
|
|
||||||
|
### Random heading
|
||||||
|
|
||||||
|
## Third Heading
|
||||||
12
test/required-headings-wrong-match-case.json
Normal file
12
test/required-headings-wrong-match-case.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"MD043": {
|
||||||
|
"headings": [
|
||||||
|
"# Title",
|
||||||
|
"## First Heading",
|
||||||
|
"## Second Heading",
|
||||||
|
"*",
|
||||||
|
"## Third Heading"
|
||||||
|
],
|
||||||
|
"match_case": true
|
||||||
|
}
|
||||||
|
}
|
||||||
11
test/required-headings-wrong-match-case.md
Normal file
11
test/required-headings-wrong-match-case.md
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Title
|
||||||
|
|
||||||
|
## First Heading
|
||||||
|
|
||||||
|
## SECOND HEADING
|
||||||
|
|
||||||
|
{MD043:5}
|
||||||
|
|
||||||
|
### Random heading
|
||||||
|
|
||||||
|
## Third Heading
|
||||||
|
|
@ -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
|
## required-headings-missing-first.md
|
||||||
|
|
||||||
> Snapshot 1
|
> 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
|
## required-headings-zero-or-more-last.md
|
||||||
|
|
||||||
> Snapshot 1
|
> Snapshot 1
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue