mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Update MD043/required-headings to support "?" meaning "exactly one unspecified heading" (fixes #475).
This commit is contained in:
parent
06b60b7372
commit
5749c8dcf7
15 changed files with 297 additions and 18 deletions
|
@ -5,7 +5,7 @@ structure for a set of files.
|
||||||
To require exactly the following structure:
|
To require exactly the following structure:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Head
|
# Heading
|
||||||
## Item
|
## Item
|
||||||
### Detail
|
### Detail
|
||||||
```
|
```
|
||||||
|
@ -14,7 +14,7 @@ Set the `headings` parameter to:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"# Head",
|
"# Heading",
|
||||||
"## Item",
|
"## Item",
|
||||||
"### Detail"
|
"### Detail"
|
||||||
]
|
]
|
||||||
|
@ -23,7 +23,7 @@ Set the `headings` parameter to:
|
||||||
To allow optional headings as with the following structure:
|
To allow optional headings as with the following structure:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Head
|
# Heading
|
||||||
## Item
|
## Item
|
||||||
### Detail (optional)
|
### Detail (optional)
|
||||||
## Foot
|
## Foot
|
||||||
|
@ -36,7 +36,7 @@ special value `"+"` meaning "one or more unspecified headings" and set the
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"# Head",
|
"# Heading",
|
||||||
"## Item",
|
"## Item",
|
||||||
"*",
|
"*",
|
||||||
"## Foot",
|
"## Foot",
|
||||||
|
@ -44,6 +44,24 @@ special value `"+"` meaning "one or more unspecified headings" and set the
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To allow a single required heading to vary as with a project name:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Project Name
|
||||||
|
## Description
|
||||||
|
## Examples
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the special value `"?"` meaning "exactly one unspecified heading":
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"?",
|
||||||
|
"## Description",
|
||||||
|
"## Examples"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
When an error is detected, this rule outputs the line number of the first
|
When an error is detected, this rule outputs the line number of the first
|
||||||
problematic heading (otherwise, it outputs the last line number of the file).
|
problematic heading (otherwise, it outputs the last line number of the file).
|
||||||
|
|
||||||
|
|
26
doc/Rules.md
26
doc/Rules.md
|
@ -1767,7 +1767,7 @@ structure for a set of files.
|
||||||
To require exactly the following structure:
|
To require exactly the following structure:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Head
|
# Heading
|
||||||
## Item
|
## Item
|
||||||
### Detail
|
### Detail
|
||||||
```
|
```
|
||||||
|
@ -1776,7 +1776,7 @@ Set the `headings` parameter to:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"# Head",
|
"# Heading",
|
||||||
"## Item",
|
"## Item",
|
||||||
"### Detail"
|
"### Detail"
|
||||||
]
|
]
|
||||||
|
@ -1785,7 +1785,7 @@ Set the `headings` parameter to:
|
||||||
To allow optional headings as with the following structure:
|
To allow optional headings as with the following structure:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Head
|
# Heading
|
||||||
## Item
|
## Item
|
||||||
### Detail (optional)
|
### Detail (optional)
|
||||||
## Foot
|
## Foot
|
||||||
|
@ -1798,7 +1798,7 @@ special value `"+"` meaning "one or more unspecified headings" and set the
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"# Head",
|
"# Heading",
|
||||||
"## Item",
|
"## Item",
|
||||||
"*",
|
"*",
|
||||||
"## Foot",
|
"## Foot",
|
||||||
|
@ -1806,6 +1806,24 @@ special value `"+"` meaning "one or more unspecified headings" and set the
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To allow a single required heading to vary as with a project name:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Project Name
|
||||||
|
## Description
|
||||||
|
## Examples
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the special value `"?"` meaning "exactly one unspecified heading":
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"?",
|
||||||
|
"## Description",
|
||||||
|
"## Examples"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
When an error is detected, this rule outputs the line number of the first
|
When an error is detected, this rule outputs the line number of the first
|
||||||
problematic heading (otherwise, it outputs the last line number of the file).
|
problematic heading (otherwise, it outputs the last line number of the file).
|
||||||
|
|
||||||
|
|
26
doc/md043.md
26
doc/md043.md
|
@ -16,7 +16,7 @@ structure for a set of files.
|
||||||
To require exactly the following structure:
|
To require exactly the following structure:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Head
|
# Heading
|
||||||
## Item
|
## Item
|
||||||
### Detail
|
### Detail
|
||||||
```
|
```
|
||||||
|
@ -25,7 +25,7 @@ Set the `headings` parameter to:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"# Head",
|
"# Heading",
|
||||||
"## Item",
|
"## Item",
|
||||||
"### Detail"
|
"### Detail"
|
||||||
]
|
]
|
||||||
|
@ -34,7 +34,7 @@ Set the `headings` parameter to:
|
||||||
To allow optional headings as with the following structure:
|
To allow optional headings as with the following structure:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Head
|
# Heading
|
||||||
## Item
|
## Item
|
||||||
### Detail (optional)
|
### Detail (optional)
|
||||||
## Foot
|
## Foot
|
||||||
|
@ -47,7 +47,7 @@ special value `"+"` meaning "one or more unspecified headings" and set the
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"# Head",
|
"# Heading",
|
||||||
"## Item",
|
"## Item",
|
||||||
"*",
|
"*",
|
||||||
"## Foot",
|
"## Foot",
|
||||||
|
@ -55,6 +55,24 @@ special value `"+"` meaning "one or more unspecified headings" and set the
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To allow a single required heading to vary as with a project name:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Project Name
|
||||||
|
## Description
|
||||||
|
## Examples
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the special value `"?"` meaning "exactly one unspecified heading":
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"?",
|
||||||
|
"## Description",
|
||||||
|
"## Examples"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
When an error is detected, this rule outputs the line number of the first
|
When an error is detected, this rule outputs the line number of the first
|
||||||
problematic heading (otherwise, it outputs the last line number of the file).
|
problematic heading (otherwise, it outputs the last line number of the file).
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ export default {
|
||||||
}
|
}
|
||||||
} else if (expected === "+") {
|
} else if (expected === "+") {
|
||||||
matchAny = true;
|
matchAny = true;
|
||||||
|
} else if (expected === "?") {
|
||||||
|
// Allow current, match next
|
||||||
} else if (handleCase(expected) === handleCase(actual)) {
|
} else if (handleCase(expected) === handleCase(actual)) {
|
||||||
matchAny = false;
|
matchAny = false;
|
||||||
} else if (matchAny) {
|
} else if (matchAny) {
|
||||||
|
|
|
@ -396,7 +396,7 @@ for (const rule of rules) {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|\\?|#{1,6}\\s+\\S.*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
|
|
|
@ -1201,7 +1201,7 @@
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|\\?|#{1,6}\\s+\\S.*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|\\?|#{1,6}\\s+\\S.*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
|
|
|
@ -1201,7 +1201,7 @@
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|\\?|#{1,6}\\s+\\S.*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^(\\*|\\+|#{1,6} .*)$"
|
"pattern": "^(\\*|\\+|\\?|#{1,6}\\s+\\S.*)$"
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
|
|
|
@ -907,7 +907,7 @@ test("readme", async(t) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("validateJsonUsingConfigSchemaStrict", async(t) => {
|
test("validateJsonUsingConfigSchemaStrict", async(t) => {
|
||||||
t.plan(187);
|
t.plan(192);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const ajv = new Ajv(ajvOptions);
|
const ajv = new Ajv(ajvOptions);
|
||||||
const validateSchemaStrict = ajv.compile(configSchemaStrict);
|
const validateSchemaStrict = ajv.compile(configSchemaStrict);
|
||||||
|
|
15
test/required-headings-question-extra.md
Normal file
15
test/required-headings-question-extra.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Project Name
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- markdownlint-configure-file {
|
||||||
|
"required-headings": {
|
||||||
|
"headings": [
|
||||||
|
"# Project Name",
|
||||||
|
"## Description",
|
||||||
|
"?"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} -->
|
||||||
|
|
||||||
|
{MD043:+1}
|
15
test/required-headings-question-first.md
Normal file
15
test/required-headings-question-first.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Project Name
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<!-- markdownlint-configure-file {
|
||||||
|
"required-headings": {
|
||||||
|
"headings": [
|
||||||
|
"?",
|
||||||
|
"## Description",
|
||||||
|
"## Examples"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} -->
|
15
test/required-headings-question-last.md
Normal file
15
test/required-headings-question-last.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Project Name
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<!-- markdownlint-configure-file {
|
||||||
|
"required-headings": {
|
||||||
|
"headings": [
|
||||||
|
"# Project Name",
|
||||||
|
"## Description",
|
||||||
|
"?"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} -->
|
15
test/required-headings-question-middle.md
Normal file
15
test/required-headings-question-middle.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Project Name
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<!-- markdownlint-configure-file {
|
||||||
|
"required-headings": {
|
||||||
|
"headings": [
|
||||||
|
"# Project Name",
|
||||||
|
"?",
|
||||||
|
"## Examples"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} -->
|
15
test/required-headings-question-missing.md
Normal file
15
test/required-headings-question-missing.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Project Name
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<!-- markdownlint-configure-file {
|
||||||
|
"required-headings": {
|
||||||
|
"headings": [
|
||||||
|
"# Project Name",
|
||||||
|
"?",
|
||||||
|
"## Examples"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} -->
|
||||||
|
|
||||||
|
{MD043:+1}
|
|
@ -48588,6 +48588,154 @@ Generated by [AVA](https://avajs.dev).
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## required-headings-question-extra.md
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
{
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
errorContext: '?',
|
||||||
|
errorDetail: null,
|
||||||
|
errorRange: null,
|
||||||
|
fixInfo: null,
|
||||||
|
lineNumber: 16,
|
||||||
|
ruleDescription: 'Required heading structure',
|
||||||
|
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md043.md',
|
||||||
|
ruleNames: [
|
||||||
|
'MD043',
|
||||||
|
'required-headings',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
fixed: `# Project Name␊
|
||||||
|
␊
|
||||||
|
## Description␊
|
||||||
|
␊
|
||||||
|
<!-- markdownlint-configure-file {␊
|
||||||
|
"required-headings": {␊
|
||||||
|
"headings": [␊
|
||||||
|
"# Project Name",␊
|
||||||
|
"## Description",␊
|
||||||
|
"?"␊
|
||||||
|
]␊
|
||||||
|
}␊
|
||||||
|
} -->␊
|
||||||
|
␊
|
||||||
|
{MD043:+1}␊
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
## required-headings-question-first.md
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
{
|
||||||
|
errors: [],
|
||||||
|
fixed: `# Project Name␊
|
||||||
|
␊
|
||||||
|
## Description␊
|
||||||
|
␊
|
||||||
|
## Examples␊
|
||||||
|
␊
|
||||||
|
<!-- markdownlint-configure-file {␊
|
||||||
|
"required-headings": {␊
|
||||||
|
"headings": [␊
|
||||||
|
"?",␊
|
||||||
|
"## Description",␊
|
||||||
|
"## Examples"␊
|
||||||
|
]␊
|
||||||
|
}␊
|
||||||
|
} -->␊
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
## required-headings-question-last.md
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
{
|
||||||
|
errors: [],
|
||||||
|
fixed: `# Project Name␊
|
||||||
|
␊
|
||||||
|
## Description␊
|
||||||
|
␊
|
||||||
|
## Examples␊
|
||||||
|
␊
|
||||||
|
<!-- markdownlint-configure-file {␊
|
||||||
|
"required-headings": {␊
|
||||||
|
"headings": [␊
|
||||||
|
"# Project Name",␊
|
||||||
|
"## Description",␊
|
||||||
|
"?"␊
|
||||||
|
]␊
|
||||||
|
}␊
|
||||||
|
} -->␊
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
## required-headings-question-middle.md
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
{
|
||||||
|
errors: [],
|
||||||
|
fixed: `# Project Name␊
|
||||||
|
␊
|
||||||
|
## Description␊
|
||||||
|
␊
|
||||||
|
## Examples␊
|
||||||
|
␊
|
||||||
|
<!-- markdownlint-configure-file {␊
|
||||||
|
"required-headings": {␊
|
||||||
|
"headings": [␊
|
||||||
|
"# Project Name",␊
|
||||||
|
"?",␊
|
||||||
|
"## Examples"␊
|
||||||
|
]␊
|
||||||
|
}␊
|
||||||
|
} -->␊
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
## required-headings-question-missing.md
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
{
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
errorContext: '## Examples',
|
||||||
|
errorDetail: null,
|
||||||
|
errorRange: null,
|
||||||
|
fixInfo: null,
|
||||||
|
lineNumber: 16,
|
||||||
|
ruleDescription: 'Required heading structure',
|
||||||
|
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md043.md',
|
||||||
|
ruleNames: [
|
||||||
|
'MD043',
|
||||||
|
'required-headings',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
fixed: `# Project Name␊
|
||||||
|
␊
|
||||||
|
## Examples␊
|
||||||
|
␊
|
||||||
|
<!-- markdownlint-configure-file {␊
|
||||||
|
"required-headings": {␊
|
||||||
|
"headings": [␊
|
||||||
|
"# Project Name",␊
|
||||||
|
"?",␊
|
||||||
|
"## Examples"␊
|
||||||
|
]␊
|
||||||
|
}␊
|
||||||
|
} -->␊
|
||||||
|
␊
|
||||||
|
{MD043:+1}␊
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
## required-headings-wrong-match-case.md
|
## required-headings-wrong-match-case.md
|
||||||
|
|
||||||
> Snapshot 1
|
> Snapshot 1
|
||||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue