diff --git a/index.js b/index.js index df62242..96fcf91 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,8 @@ * @typedef {Heading['depth']} Depth * @typedef {import('mdast-util-to-markdown').Options} Extension * - * @typedef {Partial>} Options + * @typedef {{before?: number, after?: number}} Gap + * @typedef {Partial>} Options */ /** @type {Options} */ diff --git a/readme.md b/readme.md index 649d62b..a2da0a5 100644 --- a/readme.md +++ b/readme.md @@ -8,59 +8,102 @@ [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat] -[**remark**][remark] plugin to adjust the gap between headings. - -## Important! - -This plugin is affected by the new parser in remark -([`micromark`](https://github.com/micromark/micromark), -see [`remarkjs/remark#536`](https://github.com/remarkjs/remark/pull/536)). -Use version 3 while you’re still on remark 12. -Use version 4 for remark 13+. +**[remark][]** plugin to adjust the gap between headings in markdown. + +## Contents + +* [What is this?](#what-is-this) +* [When should I use this?](#when-should-i-use-this) +* [Install](#install) +* [Use](#use) +* [API](#api) + * [`unified().use(remarkHeadingGap[, options])`](#unifieduseremarkheadinggap-options) +* [Examples](#examples) + * [Example: blank lines around first/last headings](#example-blank-lines-around-firstlast-headings) +* [Types](#types) +* [Compatibility](#compatibility) +* [Security](#security) +* [Related](#related) +* [Contribute](#contribute) +* [License](#license) + +## What is this? + +This package is a [unified][] ([remark][]) plugin that lets you change the gap +(number of blank lines) between headings and surrounding text when formatting +markdown. + +**unified** is a project that transforms content with abstract syntax trees +(ASTs). +**remark** adds support for markdown to unified. +This is a remark plugin that configures the markdown serializer +(`remark-stringify`). + +## When should I use this? + +This project is useful when you want to adjust the gap around headings when +formatting markdown. +For example, when you want two blank lines before headings with a rank of 2 +(`## Like so`). +From personal experience, adding extra blank lines helps visualize breaks in +sections, especially when quickly scanning documentation. +The default when serializing markdown with `remark-stringify` is to always +but a single blank line between blocks (headings, paragraphs, lists, code, etc). ## Install -This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): -Node 12+ is needed to use it and it must be `import`ed instead of `require`d. - -[npm][]: +This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c). +In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: ```sh npm install remark-heading-gap ``` +In Deno with [Skypack][]: + +```js +import remarkHeadingGap from 'https://cdn.skypack.dev/remark-heading-gap@5?dts' +``` + +In browsers with [Skypack][]: + +```html + +``` + ## Use -Say we have a Markdown file, `example.md`, that looks as follows: +Say we have a markdown file `example.md` that looks as follows: ```markdown # remark-heading-gap - ## Example - ## API - -### `remark.use(headingGap[, options])` - +### `unified().use(remarkHeadingGap[, options])` ## Contributing ``` -And our module, `example.js`, contains: +And our module `example.js` contains: ```js -import fs from 'node:fs' +import {read} from 'to-vfile' import {remark} from 'remark' import remarkHeadingGap from 'remark-heading-gap' -const result = remark() - .use(remarkHeadingGap) - .processSync(fs.readFileSync('example.md')) - .toString() +main() + +async function main() { + const file = await remark() + .use(remarkHeadingGap) + .process(await read('example.md')) -console.log(result) + console.log(String(file)) +} ``` -Now, running `node example` yields: +Now running `node example.js` yields: ```markdown # remark-heading-gap @@ -71,9 +114,6 @@ Now, running `node example` yields: ## API -This package exports no identifiers. -The default export is `remarkHeadingGap`. - ### `unified().use(remarkHeadingGap[, options])` @@ -82,30 +122,108 @@ The default export is `remarkHeadingGap`. ## API -### `remark().use(headingGap[, options])` +This package exports no identifiers. +The default export is `remarkHeadingGap`. + +### `unified().use(remarkHeadingGap[, options])` -Adjust the gap between headings. -Ensures that automatically generated Markdown follows your own rules for blank -lines between section headings. -From personal experience, adding extra newlines helps to visualize breaks in -sections, especially when quickly scanning documentation. +adjust the gap between headings in markdown. -#### `options.{1, 2, 3, 4, 5, 6}` +###### `options.{1, 2, 3, 4, 5, 6}` -Pass a gap (Object, default: `{before: 2, after: 1}` for `options.2`, -`{before: 1, after: 1}` for all others) -Customize the gap that appears for up to 6 levels of heading; for example, pass -`{1: {before: 2, after: 2}}` to add two blank lines before and after the first -heading. -You can also set values to `0`, to not add a blank line. +Define heading ranks to gaps (`Record<1 | 2 | 3 | 4 | 5 | 6, Gap>`, default: +`{2: {before: 2, after: 1}}`). +`Gap` is defined as `{before?: number, after?: number}`. There are no blank lines added if a heading is the first or last child of the document, list item, or block quote. +For example, pass `{1: {before: 2, after: 2}}` to add two blank lines before and +after the main heading. +You can also set values to `0` to not add blank lines. + +## Examples + +### Example: blank lines around first/last headings + +This example shows that there are no blank lines added before the first and +after the last heading in a container. +Assuming we had `example.md` from before and changed it to contain this: + +```markdown +# Alpha + +Bravo charlie. + +> ## Delta +> +> Echo foxtrott. +> +> ## Golf +``` + +Then configuring this plugin in `example.js` like so: + +```diff +@@ -6,7 +6,10 @@ main() + + async function main() { + const file = await remark() +- .use(remarkHeadingGap) ++ .use(remarkHeadingGap, { ++ 1: {before: 3, after: 3}, ++ 2: {before: 2, after: 2} ++ }) + .process(String(await read('example.md'))) + + console.log(String(file)) +``` + +Then when running `node example.js` we’d get: + +```markdown +# Alpha + + + +Bravo charlie. + +> ## Delta +> +> +> Echo foxtrott. +> +> +> ## Golf +``` + +## Types + +This package is fully typed with [TypeScript][]. +It exports `Options` and `Gap` types, which specify the interfaces of the +accepted options. + +## Compatibility + +Projects maintained by the unified collective are compatible with all 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. + +This plugin works with `remark-stringify` version 9+ (`remark` version 13+). +Version 3 of this plugin worked with `remark-stringify` version 8- (`remark` +version 12-). + ## Security -Use of `remark-heading-gap` does not involve [**rehype**][rehype] -([**hast**][hast]) or user content so there are no openings for -[cross-site scripting (XSS)][xss] attacks. +Use of `remark-heading-gap` does not involve **[rehype][]** (**[hast][]**) or +user content so there are no openings for [cross-site scripting (XSS)][xss] +attacks. + +## Related + +* [`remarkjs/remark-normalize-headings`](https://github.com/remarkjs/remark-normalize-headings) + — make sure there is a single top level heading in a document by adjusting + heading ranks accordingly ## Contribute @@ -151,6 +269,8 @@ abide by its terms. [npm]: https://docs.npmjs.com/cli/install +[skypack]: https://www.skypack.dev + [health]: https://github.com/remarkjs/.github [contributing]: https://github.com/remarkjs/.github/blob/HEAD/contributing.md @@ -165,8 +285,12 @@ abide by its terms. [remark]: https://github.com/remarkjs/remark +[unified]: https://github.com/unifiedjs/unified + [xss]: https://en.wikipedia.org/wiki/Cross-site_scripting +[typescript]: https://www.typescriptlang.org + [rehype]: https://github.com/rehypejs/rehype [hast]: https://github.com/syntax-tree/hast