mirror of
https://github.com/remarkjs/remark-lint.git
synced 2024-09-11 19:57:15 +03:00
Add no-duplicate-headings-in-section
rule
This new rule warns when headings exist on the same level, in the same section. This rule is not yet in any preset. Closes GH-84.
This commit is contained in:
parent
1c3f0a3446
commit
f113f596c4
45
doc/rules.md
45
doc/rules.md
@ -2,7 +2,7 @@
|
||||
|
||||
# List of Rules
|
||||
|
||||
This document describes all (58)
|
||||
This document describes all (59)
|
||||
available rules, what they check for, examples of
|
||||
what they warn for, and how to fix their warnings.
|
||||
|
||||
@ -93,6 +93,7 @@ For example, as follows:
|
||||
- [no-blockquote-without-caret](#no-blockquote-without-caret)
|
||||
- [no-consecutive-blank-lines](#no-consecutive-blank-lines)
|
||||
- [no-duplicate-definitions](#no-duplicate-definitions)
|
||||
- [no-duplicate-headings-in-section](#no-duplicate-headings-in-section)
|
||||
- [no-duplicate-headings](#no-duplicate-headings)
|
||||
- [no-emphasis-as-heading](#no-emphasis-as-heading)
|
||||
- [no-file-name-articles](#no-file-name-articles)
|
||||
@ -1392,6 +1393,48 @@ When this rule is turned on, the following file
|
||||
2:1-2:11: Do not use definitions with the same identifier (1:1)
|
||||
```
|
||||
|
||||
## `no-duplicate-headings-in-section`
|
||||
|
||||
Warn when duplicate headings are found,
|
||||
but only when on the same level, “in”
|
||||
the same section.
|
||||
|
||||
When this rule is turned on, the following file
|
||||
`valid.md` is ok:
|
||||
|
||||
```markdown
|
||||
## Alpha
|
||||
|
||||
### Bravo
|
||||
|
||||
## Charlie
|
||||
|
||||
### Bravo
|
||||
|
||||
### Delta
|
||||
|
||||
#### Bravo
|
||||
|
||||
#### Echo
|
||||
|
||||
##### Bravo
|
||||
```
|
||||
|
||||
When this rule is turned on, the following file
|
||||
`invalid.md` is **not** ok:
|
||||
|
||||
```markdown
|
||||
## Foxtrot
|
||||
|
||||
### Golf
|
||||
|
||||
### Golf
|
||||
```
|
||||
|
||||
```text
|
||||
5:1-5:9: Do not use headings with similar content per section (3:1)
|
||||
```
|
||||
|
||||
## `no-duplicate-headings`
|
||||
|
||||
Warn when duplicate headings are found.
|
||||
|
@ -28,6 +28,7 @@ module.exports = {
|
||||
'no-blockquote-without-caret': require('./rules/no-blockquote-without-caret.js'),
|
||||
'no-consecutive-blank-lines': require('./rules/no-consecutive-blank-lines.js'),
|
||||
'no-duplicate-definitions': require('./rules/no-duplicate-definitions.js'),
|
||||
'no-duplicate-headings-in-section': require('./rules/no-duplicate-headings-in-section.js'),
|
||||
'no-duplicate-headings': require('./rules/no-duplicate-headings.js'),
|
||||
'no-emphasis-as-heading': require('./rules/no-emphasis-as-heading.js'),
|
||||
'no-file-name-articles': require('./rules/no-file-name-articles.js'),
|
||||
|
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @author Titus Wormer
|
||||
* @copyright 2015 Titus Wormer
|
||||
* @license MIT
|
||||
* @module no-duplicate-headings-in-section
|
||||
* @fileoverview
|
||||
* Warn when duplicate headings are found,
|
||||
* but only when on the same level, “in”
|
||||
* the same section.
|
||||
*
|
||||
* @example {"name": "valid.md"}
|
||||
*
|
||||
* ## Alpha
|
||||
*
|
||||
* ### Bravo
|
||||
*
|
||||
* ## Charlie
|
||||
*
|
||||
* ### Bravo
|
||||
*
|
||||
* ### Delta
|
||||
*
|
||||
* #### Bravo
|
||||
*
|
||||
* #### Echo
|
||||
*
|
||||
* ##### Bravo
|
||||
*
|
||||
* @example {"name": "invalid.md", "label": "input"}
|
||||
*
|
||||
* ## Foxtrot
|
||||
*
|
||||
* ### Golf
|
||||
*
|
||||
* ### Golf
|
||||
*
|
||||
* @example {"name": "invalid.md", "label": "output"}
|
||||
*
|
||||
* 5:1-5:9: Do not use headings with similar content per section (3:1)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/* Dependencies. */
|
||||
var position = require('unist-util-position');
|
||||
var visit = require('unist-util-visit');
|
||||
var toString = require('mdast-util-to-string');
|
||||
|
||||
/* Expose. */
|
||||
module.exports = noDuplicateHeadingsInSection;
|
||||
|
||||
/* Warn when headings with equal content are found in
|
||||
* a section. Case-insensitive. */
|
||||
function noDuplicateHeadingsInSection(tree, file) {
|
||||
var stack = [{}];
|
||||
|
||||
visit(tree, 'heading', function (node) {
|
||||
var depth = node.depth;
|
||||
var siblings = stack[depth - 1] || {};
|
||||
var value = toString(node).toUpperCase();
|
||||
var duplicate = siblings[value];
|
||||
var pos;
|
||||
|
||||
stack = stack.slice(0, depth);
|
||||
stack[depth] = {};
|
||||
siblings[value] = node;
|
||||
|
||||
if (!position.generated(node) && duplicate && duplicate.type === 'heading') {
|
||||
pos = position.start(duplicate);
|
||||
file.message(
|
||||
'Do not use headings with similar content per section (' +
|
||||
pos.line + ':' + pos.column + ')',
|
||||
node
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user