Socket
Socket
Sign inDemoInstall

remark-lint-no-duplicate-headings

Package Overview
Dependencies
Maintainers
3
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

remark-lint-no-duplicate-headings - npm Package Compare versions

Comparing version 3.1.2 to 4.0.0

index.d.ts.map

15

index.d.ts

@@ -1,7 +0,8 @@

export default remarkLintNoDuplicateHeadings
export type Root = import('mdast').Root
declare const remarkLintNoDuplicateHeadings: import('unified').Plugin<
void[] | [unknown],
import('mdast').Root,
import('mdast').Root
>
export default remarkLintNoDuplicateHeadings;
export type Nodes = import('mdast').Nodes;
export type Root = import('mdast').Root;
declare const remarkLintNoDuplicateHeadings: {
(config?: unknown): ((tree: import("mdast").Root, file: import("vfile").VFile, next: import("unified").TransformCallback<import("mdast").Root>) => undefined) | undefined;
readonly name: string;
};
//# sourceMappingURL=index.d.ts.map
/**
* remark-lint rule to warn when the same text is used in multiple headings.
*
* ## What is this?
*
* This package checks that headings are unique.
*
* ## When should I use this?
*
* You can use this package to check that headings with the same text are
* used once.
* You can use this package to check that headings are unique.
*
* ## API
*
* ### `unified().use(remarkLintNoDuplicateHeadings)`
*
* Warn when the same text is used in multiple headings.
*
* ###### Parameters
*
* There are no options.
*
* ###### Returns
*
* Transform ([`Transformer` from `unified`][github-unified-transformer]).
*
* ## Recommendation
*
* Headings having unique text helps screen reader users (who typically use
* “jump to heading” features to navigate within a page, which reads headings
* out loud).
* It also helps because often headings receive automatic unique IDs, and when
* the same heading text is used, they are suffixed with a number based on where
* they are positioned in the document, which makes linking to them prone to
* changes.
* Headings having unique text helps screen reader users,
* who typically use “jump to heading” features to navigate within a page,
* which reads headings out loud.
*
* It also helps because often headings receive automatic unique IDs,
* and when the same heading text is used,
* they are suffixed with a number based on where they are positioned in the
* document,
* which makes linking to them prone to changes.
*
* [api-remark-lint-no-duplicate-headings]: #unifieduseremarklintnoduplicateheadings
* [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer
*
* @module no-duplicate-headings
* @summary
* remark-lint rule to warn when headings with the same text are found.
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
*
* @example
* {"name": "ok.md"}
*
* # Foo
* # Mercury
*
* ## Bar
* ## Venus
*
* @example
* {"name": "not-ok.md", "label": "input"}
* {"label": "input", "name": "not-ok.md"}
*
* # Foo
* # Mercury
*
* ## Foo
* ## Mercury
*
* ## [Foo](http://foo.com/bar)
* ## [Mercury](http://example.com/mercury/)
* @example
* {"label": "output", "name": "not-ok.md"}
*
* 3:1-3:11: Unexpected heading with equivalent text, expected unique headings
* 5:1-5:42: Unexpected heading with equivalent text, expected unique headings
*
* @example
* {"name": "not-ok.md", "label": "output"}
* {"label": "input", "mdx": true, "name": "mdx.mdx"}
*
* 3:1-3:7: Do not use headings with similar content (1:1)
* 5:1-5:29: Do not use headings with similar content (3:1)
* <h1>Mercury</h1>
* <h2>Mercury</h2>
* @example
* {"label": "output", "mdx": true, "name": "mdx.mdx"}
*
* 2:1-2:17: Unexpected heading with equivalent text, expected unique headings
*/
/**
* @typedef {import('mdast').Nodes} Nodes
* @typedef {import('mdast').Root} Root
*/
/// <reference types="mdast-util-mdx" />
import {ok as assert} from 'devlop'
import {toString} from 'mdast-util-to-string'
import {lintRule} from 'unified-lint-rule'
import {pointStart} from 'unist-util-position'
import {generated} from 'unist-util-generated'
import {visit} from 'unist-util-visit'
import {stringifyPosition} from 'unist-util-stringify-position'
import {toString} from 'mdast-util-to-string'
import {visitParents} from 'unist-util-visit-parents'
import {VFileMessage} from 'vfile-message'
const jsxNameRe = /^h([1-6])$/
const remarkLintNoDuplicateHeadings = lintRule(

@@ -66,20 +98,44 @@ {

},
/** @type {import('unified-lint-rule').Rule<Root, void>} */
(tree, file) => {
/** @type {Record<string, string>} */
const map = Object.create(null)
/**
* @param {Root} tree
* Tree.
* @returns {undefined}
* Nothing.
*/
function (tree, file) {
/** @type {Map<string, Array<Nodes>>} */
const map = new Map()
visit(tree, 'heading', (node) => {
if (!generated(node)) {
const value = toString(node).toUpperCase()
const duplicate = map[value]
visitParents(tree, function (node, parents) {
if (
node.type === 'heading' ||
((node.type === 'mdxJsxFlowElement' ||
node.type === 'mdxJsxTextElement') &&
node.name &&
jsxNameRe.test(node.name))
) {
const ancestors = [...parents, node]
const value = toString(node).toLowerCase()
const duplicateAncestors = map.get(value)
if (duplicate) {
if (node.position && duplicateAncestors) {
const duplicate = duplicateAncestors.at(-1)
assert(duplicate) // Always defined.
file.message(
'Do not use headings with similar content (' + duplicate + ')',
node
'Unexpected heading with equivalent text, expected unique headings',
{
ancestors,
cause: new VFileMessage('Equivalent heading text defined here', {
ancestors: duplicateAncestors,
place: duplicate.position,
source: 'remark-lint',
ruleId: 'no-duplicate-headings'
}),
place: node.position
}
)
}
map[value] = stringifyPosition(pointStart(node))
map.set(value, ancestors)
}

@@ -86,0 +142,0 @@ })

{
"name": "remark-lint-no-duplicate-headings",
"version": "3.1.2",
"version": "4.0.0",
"description": "remark-lint rule to warn on duplicate headings",
"license": "MIT",
"keywords": [
"duplicate",
"heading",
"lint",
"remark",
"lint",
"rule",
"remark-lint",
"remark-lint-rule",
"duplicate",
"heading"
"rule"
],
"repository": {
"type": "git",
"url": "https://github.com/remarkjs/remark-lint",
"directory": "packages/remark-lint-no-duplicate-headings"
},
"repository": "https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-duplicate-headings",
"bugs": "https://github.com/remarkjs/remark-lint/issues",

@@ -26,30 +23,34 @@ "funding": {

"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
"Titus Wormer <tituswormer@gmail.com>"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"exports": "./index.js",
"files": [
"index.d.ts",
"index.d.ts.map",
"index.js"
],
"dependencies": {
"@types/mdast": "^3.0.0",
"mdast-util-to-string": "^3.0.0",
"unified": "^10.0.0",
"unified-lint-rule": "^2.0.0",
"unist-util-generated": "^2.0.0",
"unist-util-position": "^4.0.0",
"unist-util-stringify-position": "^3.0.0",
"unist-util-visit": "^4.0.0"
"@types/mdast": "^4.0.0",
"devlop": "^1.0.0",
"mdast-util-mdx": "^3.0.0",
"mdast-util-to-string": "^4.0.0",
"unified-lint-rule": "^3.0.0",
"unist-util-visit-parents": "^6.0.0",
"vfile-message": "^4.0.0"
},
"scripts": {},
"xo": false,
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true,
"ignoreCatch": true
"ignoreCatch": true,
"strict": true
},
"xo": {
"prettier": true,
"rules": {
"capitalized-comments": "off"
}
}
}

@@ -5,43 +5,40 @@ <!--This file is generated-->

[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[![Build][badge-build-image]][badge-build-url]
[![Coverage][badge-coverage-image]][badge-coverage-url]
[![Downloads][badge-downloads-image]][badge-downloads-url]
[![Size][badge-size-image]][badge-size-url]
[![Sponsors][badge-funding-sponsors-image]][badge-funding-url]
[![Backers][badge-funding-backers-image]][badge-funding-url]
[![Chat][badge-chat-image]][badge-chat-url]
[`remark-lint`][mono] rule to warn when headings with the same text are found.
[`remark-lint`][github-remark-lint] rule to warn when the same text is used in multiple headings.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Presets](#presets)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`unified().use(remarkLintNoDuplicateHeadings[, config])`](#unifieduseremarklintnoduplicateheadings-config)
* [Recommendation](#recommendation)
* [Examples](#examples)
* [Compatibility](#compatibility)
* [Contribute](#contribute)
* [License](#license)
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Presets](#presets)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`unified().use(remarkLintNoDuplicateHeadings)`](#unifieduseremarklintnoduplicateheadings)
* [Recommendation](#recommendation)
* [Examples](#examples)
* [Compatibility](#compatibility)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a [unified][] ([remark][]) plugin, specifically a `remark-lint`
rule.
Lint rules check markdown code style.
This package checks that headings are unique.
## When should I use this?
You can use this package to check that headings with the same text are
used once.
You can use this package to check that headings are unique.
## Presets
This rule is included in the following presets:
This plugin is included in the following presets:
| Preset | Setting |
| Preset | Options |
| - | - |

@@ -52,4 +49,5 @@ | [`remark-preset-lint-markdown-style-guide`](https://github.com/remarkjs/remark-lint/tree/main/packages/remark-preset-lint-markdown-style-guide) | |

This package is [ESM only][esm].
In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]:
This package is [ESM only][github-gist-esm].
In Node.js (version 16+),
install with [npm][npm-install]:

@@ -60,13 +58,13 @@ ```sh

In Deno with [`esm.sh`][esmsh]:
In Deno with [`esm.sh`][esm-sh]:
```js
import remarkLintNoDuplicateHeadings from 'https://esm.sh/remark-lint-no-duplicate-headings@3'
import remarkLintNoDuplicateHeadings from 'https://esm.sh/remark-lint-no-duplicate-headings@4'
```
In browsers with [`esm.sh`][esmsh]:
In browsers with [`esm.sh`][esm-sh]:
```html
<script type="module">
import remarkLintNoDuplicateHeadings from 'https://esm.sh/remark-lint-no-duplicate-headings@3?bundle'
import remarkLintNoDuplicateHeadings from 'https://esm.sh/remark-lint-no-duplicate-headings@4?bundle'
</script>

@@ -80,18 +78,20 @@ ```

```js
import remarkLint from 'remark-lint'
import remarkLintNoDuplicateHeadings from 'remark-lint-no-duplicate-headings'
import remarkParse from 'remark-parse'
import remarkStringify from 'remark-stringify'
import {read} from 'to-vfile'
import {unified} from 'unified'
import {reporter} from 'vfile-reporter'
import {remark} from 'remark'
import remarkLint from 'remark-lint'
import remarkLintNoDuplicateHeadings from 'remark-lint-no-duplicate-headings'
main()
const file = await read('example.md')
async function main() {
const file = await remark()
.use(remarkLint)
.use(remarkLintNoDuplicateHeadings)
.process(await read('example.md'))
await unified()
.use(remarkParse)
.use(remarkLint)
.use(remarkLintNoDuplicateHeadings)
.use(remarkStringify)
.process(file)
console.error(reporter(file))
}
console.error(reporter(file))
```

@@ -102,3 +102,3 @@

```sh
remark --use remark-lint --use remark-lint-no-duplicate-headings example.md
remark --frail --use remark-lint --use remark-lint-no-duplicate-headings .
```

@@ -124,21 +124,30 @@

This package exports no identifiers.
The default export is `remarkLintNoDuplicateHeadings`.
It exports no additional [TypeScript][typescript] types.
The default export is
[`remarkLintNoDuplicateHeadings`][api-remark-lint-no-duplicate-headings].
### `unified().use(remarkLintNoDuplicateHeadings[, config])`
### `unified().use(remarkLintNoDuplicateHeadings)`
This rule supports standard configuration that all remark lint rules accept
(such as `false` to turn it off or `[1, options]` to configure it).
Warn when the same text is used in multiple headings.
###### Parameters
There are no options.
###### Returns
Transform ([`Transformer` from `unified`][github-unified-transformer]).
## Recommendation
Headings having unique text helps screen reader users (who typically use
“jump to heading” features to navigate within a page, which reads headings
out loud).
It also helps because often headings receive automatic unique IDs, and when
the same heading text is used, they are suffixed with a number based on where
they are positioned in the document, which makes linking to them prone to
changes.
Headings having unique text helps screen reader users,
who typically use “jump to heading” features to navigate within a page,
which reads headings out loud.
It also helps because often headings receive automatic unique IDs,
and when the same heading text is used,
they are suffixed with a number based on where they are positioned in the
document,
which makes linking to them prone to changes.
## Examples

@@ -151,5 +160,5 @@

```markdown
# Foo
# Mercury
## Bar
## Venus
```

@@ -166,7 +175,7 @@

```markdown
# Foo
# Mercury
## Foo
## Mercury
## [Foo](http://foo.com/bar)
## [Mercury](http://example.com/mercury/)
```

@@ -177,20 +186,42 @@

```text
3:1-3:7: Do not use headings with similar content (1:1)
5:1-5:29: Do not use headings with similar content (3:1)
3:1-3:11: Unexpected heading with equivalent text, expected unique headings
5:1-5:42: Unexpected heading with equivalent text, expected unique headings
```
##### `mdx.mdx`
###### In
> 👉 **Note**: this example uses
> MDX ([`remark-mdx`][github-remark-mdx]).
```mdx
<h1>Mercury</h1>
<h2>Mercury</h2>
```
###### Out
```text
2:1-2:17: Unexpected heading with equivalent text, expected unique headings
```
## Compatibility
Projects maintained by the unified collective are compatible with all maintained
Projects maintained by the unified collective are compatible with maintained
versions of Node.js.
As of now, that is Node.js 12.20+, 14.14+, and 16.0+.
Our projects sometimes work with older versions, but this is not guaranteed.
When we cut a new major release, we drop support for unmaintained versions of
Node.
This means we try to keep the current release line,
`remark-lint-no-duplicate-headings@4`,
compatible with Node.js 16.
## Contribute
See [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways
See [`contributing.md`][github-dotfiles-contributing] in [`remarkjs/.github`][github-dotfiles-health] for ways
to get started.
See [`support.md`][support] for ways to get help.
See [`support.md`][github-dotfiles-support] for ways to get help.
This project has a [code of conduct][coc].
This project has a [code of conduct][github-dotfiles-coc].
By interacting with this repository, organization, or community you agree to

@@ -201,52 +232,56 @@ abide by its terms.

[MIT][license] © [Titus Wormer][author]
[MIT][file-license] © [Titus Wormer][author]
[build-badge]: https://github.com/remarkjs/remark-lint/workflows/main/badge.svg
[api-remark-lint-no-duplicate-headings]: #unifieduseremarklintnoduplicateheadings
[build]: https://github.com/remarkjs/remark-lint/actions
[author]: https://wooorm.com
[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark-lint.svg
[badge-build-image]: https://github.com/remarkjs/remark-lint/workflows/main/badge.svg
[coverage]: https://codecov.io/github/remarkjs/remark-lint
[badge-build-url]: https://github.com/remarkjs/remark-lint/actions
[downloads-badge]: https://img.shields.io/npm/dm/remark-lint-no-duplicate-headings.svg
[badge-chat-image]: https://img.shields.io/badge/chat-discussions-success.svg
[downloads]: https://www.npmjs.com/package/remark-lint-no-duplicate-headings
[badge-chat-url]: https://github.com/remarkjs/remark/discussions
[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-lint-no-duplicate-headings.svg
[badge-coverage-image]: https://img.shields.io/codecov/c/github/remarkjs/remark-lint.svg
[size]: https://bundlephobia.com/result?p=remark-lint-no-duplicate-headings
[badge-coverage-url]: https://codecov.io/github/remarkjs/remark-lint
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[badge-downloads-image]: https://img.shields.io/npm/dm/remark-lint-no-duplicate-headings.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[badge-downloads-url]: https://www.npmjs.com/package/remark-lint-no-duplicate-headings
[collective]: https://opencollective.com/unified
[badge-funding-backers-image]: https://opencollective.com/unified/backers/badge.svg
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[badge-funding-sponsors-image]: https://opencollective.com/unified/sponsors/badge.svg
[chat]: https://github.com/remarkjs/remark/discussions
[badge-funding-url]: https://opencollective.com/unified
[unified]: https://github.com/unifiedjs/unified
[badge-size-image]: https://img.shields.io/bundlejs/size/remark-lint-no-duplicate-headings
[remark]: https://github.com/remarkjs/remark
[badge-size-url]: https://bundlejs.com/?q=remark-lint-no-duplicate-headings
[mono]: https://github.com/remarkjs/remark-lint
[esm-sh]: https://esm.sh
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[file-license]: https://github.com/remarkjs/remark-lint/blob/main/license
[esmsh]: https://esm.sh
[github-dotfiles-coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md
[npm]: https://docs.npmjs.com/cli/install
[github-dotfiles-contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md
[health]: https://github.com/remarkjs/.github
[github-dotfiles-health]: https://github.com/remarkjs/.github
[contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md
[github-dotfiles-support]: https://github.com/remarkjs/.github/blob/main/support.md
[support]: https://github.com/remarkjs/.github/blob/main/support.md
[github-gist-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md
[github-remark-lint]: https://github.com/remarkjs/remark-lint
[license]: https://github.com/remarkjs/remark-lint/blob/main/license
[github-remark-mdx]: https://mdxjs.com/packages/remark-mdx/
[author]: https://wooorm.com
[github-unified-transformer]: https://github.com/unifiedjs/unified#transformer
[npm-install]: https://docs.npmjs.com/cli/install
[typescript]: https://www.typescriptlang.org
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc