{"id":13483611,"url":"https://github.com/rehypejs/rehype-autolink-headings","last_synced_at":"2025-03-27T14:31:24.362Z","repository":{"id":42479964,"uuid":"71642715","full_name":"rehypejs/rehype-autolink-headings","owner":"rehypejs","description":"plugin to add links to headings in HTML","archived":false,"fork":false,"pushed_at":"2023-11-08T11:57:43.000Z","size":122,"stargazers_count":191,"open_issues_count":0,"forks_count":9,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-05-17T20:45:19.878Z","etag":null,"topics":["heading","html","link","rehype","rehype-plugin"],"latest_commit_sha":null,"homepage":"https://unifiedjs.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rehypejs.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"unifiedjs","open_collective":"unified"}},"created_at":"2016-10-22T14:01:45.000Z","updated_at":"2024-05-31T22:54:18.324Z","dependencies_parsed_at":"2023-11-08T12:41:40.857Z","dependency_job_id":"2fa012e0-4af8-4486-841d-e00da30997bf","html_url":"https://github.com/rehypejs/rehype-autolink-headings","commit_stats":{"total_commits":94,"total_committers":5,"mean_commits":18.8,"dds":0.05319148936170215,"last_synced_commit":"a37d231c4c0c29c6880d8e1b6842dfbd771027dc"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehypejs%2Frehype-autolink-headings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehypejs%2Frehype-autolink-headings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehypejs%2Frehype-autolink-headings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehypejs%2Frehype-autolink-headings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rehypejs","download_url":"https://codeload.github.com/rehypejs/rehype-autolink-headings/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245401351,"owners_count":20609166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["heading","html","link","rehype","rehype-plugin"],"created_at":"2024-07-31T17:01:13.304Z","updated_at":"2025-03-27T14:31:23.924Z","avatar_url":"https://github.com/rehypejs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/unifiedjs","https://opencollective.com/unified"],"categories":["JavaScript","编辑器相关"],"sub_categories":[],"readme":"# rehype-autolink-headings\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\n**[rehype][]** plugin to add links from headings back to themselves.\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`unified().use(rehypeAutolinkHeadings[, options])`](#unifieduserehypeautolinkheadings-options)\n  * [`Behavior`](#behavior)\n  * [`Build`](#build)\n  * [`BuildProperties`](#buildproperties)\n  * [`Options`](#options)\n* [Examples](#examples)\n  * [Example: different behaviors](#example-different-behaviors)\n  * [Example: building content with `hastscript`](#example-building-content-with-hastscript)\n  * [Example: passing content from a string of HTML](#example-passing-content-from-a-string-of-html)\n  * [Example: group](#example-group)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Related](#related)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a [unified][] ([rehype][]) plugin to add links from headings\nback to themselves.\nIt looks for headings (so `\u003ch1\u003e` through `\u003ch6\u003e`) that have `id` properties,\nand injects a link to themselves.\nSimilar functionality is applied by many places that render markdown.\nFor example, when browsing this readme on GitHub or npm, an anchor is added\nto headings, which you can share to point people to a particular place in a\ndocument.\n\n**unified** is a project that transforms content with abstract syntax trees\n(ASTs).\n**rehype** adds support for HTML to unified.\n**hast** is the HTML AST that rehype uses.\nThis is a rehype plugin that adds links to headings in the AST.\n\n## When should I use this?\n\nThis plugin is useful when you have relatively long documents, where you want\nusers to be able to link to particular sections, and you already have `id`\nproperties set on all (or certain?) headings.\n\nA different plugin, [`rehype-slug`][rehype-slug], adds `id`s to headings.\nWhen a heading doesn’t already have an `id` property, it creates a slug from\nit, and adds that as the `id` property.\nWhen using both plugins together, all headings (whether explicitly with a\ncertain `id` or automatically with a generate one) will get a link back to\nthemselves.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install rehype-autolink-headings\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```js\nimport rehypeAutolinkHeadings from 'https://esm.sh/rehype-autolink-headings@7'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import rehypeAutolinkHeadings from 'https://esm.sh/rehype-autolink-headings@7?bundle'\n\u003c/script\u003e\n```\n\n## Use\n\nSay we have the following file `example.html`:\n\n```html\n\u003ch1\u003eSolar System\u003c/h1\u003e\n\u003ch2\u003eFormation and evolution\u003c/h2\u003e\n\u003ch2\u003eStructure and composition\u003c/h2\u003e\n\u003ch3\u003eOrbits\u003c/h3\u003e\n\u003ch3\u003eComposition\u003c/h3\u003e\n\u003ch3\u003eDistances and scales\u003c/h3\u003e\n\u003ch3\u003eInterplanetary environment\u003c/h3\u003e\n\u003cp\u003e…\u003c/p\u003e\n```\n\n…and our module `example.js` contains:\n\n```js\nimport {rehype} from 'rehype'\nimport rehypeAutolinkHeadings from 'rehype-autolink-headings'\nimport rehypeSlug from 'rehype-slug'\nimport {read} from 'to-vfile'\n\nconst file = await rehype()\n  .data('settings', {fragment: true})\n  .use(rehypeSlug)\n  .use(rehypeAutolinkHeadings)\n  .process(await read('example.html'))\n\nconsole.log(String(file))\n```\n\n…then running `node example.js` yields:\n\n```html\n\u003ch1 id=\"solar-system\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#solar-system\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eSolar System\u003c/h1\u003e\n\u003ch2 id=\"formation-and-evolution\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#formation-and-evolution\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eFormation and evolution\u003c/h2\u003e\n\u003ch2 id=\"structure-and-composition\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#structure-and-composition\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eStructure and composition\u003c/h2\u003e\n\u003ch3 id=\"orbits\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#orbits\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eOrbits\u003c/h3\u003e\n\u003ch3 id=\"composition\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#composition\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eComposition\u003c/h3\u003e\n\u003ch3 id=\"distances-and-scales\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#distances-and-scales\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eDistances and scales\u003c/h3\u003e\n\u003ch3 id=\"interplanetary-environment\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#interplanetary-environment\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eInterplanetary environment\u003c/h3\u003e\n\u003cp\u003e…\u003c/p\u003e\n```\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`rehypeAutolinkHeadings`][api-rehype-autolink-headings].\n\n### `unified().use(rehypeAutolinkHeadings[, options])`\n\nAdd links from headings back to themselves.\n\n###### Parameters\n\n* `options` ([`Options`][api-options], optional)\n  — configuration\n\n###### Returns\n\nTransform ([`Transformer`][unified-transformer]).\n\n###### Notes\n\nThis plugin only applies to headings with `id`s.\nUse `rehype-slug` to generate `id`s for headings that don’t have them.\n\nSeveral behaviors are supported:\n\n* `'prepend'` (default) — inject link before the heading text\n* `'append'` — inject link after the heading text\n* `'wrap'` — wrap the whole heading text with the link\n* `'before'` — insert link before the heading\n* `'after'` — insert link after the heading\n\n### `Behavior`\n\nBehavior (TypeScript type).\n\n###### Type\n\n```ts\ntype Behavior = 'after' | 'append' | 'before' | 'prepend' | 'wrap'\n```\n\n### `Build`\n\nGenerate content (TypeScript type).\n\n###### Parameters\n\n* `element` ([`Element`][hast-element])\n  — current heading\n\n###### Returns\n\nContent ([`Array\u003cNode\u003e`][hast-node] or `Node`).\n\n### `BuildProperties`\n\nGenerate properties (TypeScript type).\n\n###### Parameters\n\n* `element` ([`Element`][hast-element])\n  — current heading\n\n###### Returns\n\nProperties ([`Properties`][hast-properties]).\n\n### `Options`\n\nConfiguration (TypeScript type).\n\n###### Fields\n\n* `behavior` ([`Behavior`][api-behavior], default: `'prepend'`)\n  — how to create links\n* `content` ([`Array\u003cNode\u003e`][hast-node], `Node`, or [`Build`][api-build],\n  default: if `'wrap'` then `undefined`, otherwise equivalent of\n  `\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e`)\n  — content to insert in the link;\n  if `behavior` is `'wrap'` and `Build` is passed, its result replaces the\n  existing content, otherwise the content is added after existing content\n* `group` ([`Array\u003cNode\u003e`][hast-node], `Node`, or [`Build`][api-build],\n  optional)\n  — content to wrap the heading and link with, if `behavior` is `'after'` or\n  `'before'`\n* `headingProperties` ([`BuildProperties`][api-build-properties] or\n  [`Properties`][hast-properties], optional)\n  — extra properties to set on the heading\n* `properties` ([`BuildProperties`][api-build-properties] or\n  [`Properties`][hast-properties], default:\n  `{ariaHidden: true, tabIndex: -1}` if `'append'` or `'prepend'`, otherwise\n  `undefined`)\n  — extra properties to set on the link when injecting\n* `test` ([`Test`][hast-util-is-element-test], optional)\n  — extra test for which headings are linked\n\n## Examples\n\n### Example: different behaviors\n\nThis example shows what each behavior generates by default.\n\n```js\nimport {rehype} from 'rehype'\nimport rehypeAutolinkHeadings from 'rehype-autolink-headings'\n\nconst behaviors = ['after', 'append', 'before', 'prepend', 'wrap']\nlet index = -1\nwhile (++index \u003c behaviors.length) {\n  const behavior = behaviors[index]\n  console.log(\n    String(\n      await rehype()\n        .data('settings', {fragment: true})\n        .use(rehypeAutolinkHeadings, {behavior})\n        .process('\u003ch1 id=\"' + behavior + '\"\u003e' + behavior + '\u003c/h1\u003e')\n    )\n  )\n}\n```\n\nYields:\n\n```html\n\u003ch1 id=\"after\"\u003eafter\u003c/h1\u003e\u003ca href=\"#after\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003e\n\u003ch1 id=\"append\"\u003eappend\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#append\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003e\u003c/h1\u003e\n\u003ca href=\"#before\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003e\u003ch1 id=\"before\"\u003ebefore\u003c/h1\u003e\n\u003ch1 id=\"prepend\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#prepend\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003eprepend\u003c/h1\u003e\n\u003ch1 id=\"wrap\"\u003e\u003ca href=\"#wrap\"\u003ewrap\u003c/a\u003e\u003c/h1\u003e\n```\n\n### Example: building content with `hastscript`\n\nThe following example passes `options.content` as a function, to generate an\naccessible description specific to each link.\nIt uses [`hastscript`][hastscript] to build nodes.\n\n```js\nimport {h} from 'hastscript'\nimport {toString} from 'hast-util-to-string'\nimport {rehype} from 'rehype'\nimport rehypeAutolinkHeadings from 'rehype-autolink-headings'\n\nconst file = await rehype()\n  .data('settings', {fragment: true})\n  .use(rehypeAutolinkHeadings, {\n    content(node) {\n      return [\n        h('span.visually-hidden', 'Read the “', toString(node), '” section'),\n        h('span.icon.icon-link', {ariaHidden: 'true'})\n      ]\n    }\n  })\n  .process('\u003ch1 id=\"pluto\"\u003ePluto\u003c/h1\u003e')\n\nconsole.log(String(file))\n```\n\nYields:\n\n```html\n\u003ch1 id=\"pluto\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#pluto\"\u003e\u003cspan class=\"visually-hidden\"\u003eRead the “Pluto” section\u003c/span\u003e\u003cspan class=\"icon icon-link\" aria-hidden=\"true\"\u003e\u003c/span\u003e\u003c/a\u003ePluto\u003c/h1\u003e\n```\n\n### Example: passing content from a string of HTML\n\nThe following example passes `content` as nodes.\nIt uses [`hast-util-from-html-isomorphic`][hast-util-from-html-isomorphic] to\nbuild nodes from a string of HTML.\n\n```js\n/**\n * @import {ElementContent} from 'hast'\n */\n\nimport {fromHtmlIsomorphic} from 'hast-util-from-html-isomorphic'\nimport {rehype} from 'rehype'\nimport rehypeAutolinkHeadings from 'rehype-autolink-headings'\n\nconst file = await rehype()\n  .data('settings', {fragment: true})\n  .use(rehypeAutolinkHeadings, {\n    content: /** @type {Array\u003cElementContent\u003e} */ (\n      fromHtmlIsomorphic(\n        '\u003csvg height=\"10\" width=\"10\"\u003e\u003ccircle cx=\"5\" cy=\"5\" r=\"5\" fill=\"black\" /\u003e\u003c/svg\u003e',\n        {fragment: true}\n      ).children\n    )\n  })\n  .process('\u003ch1 id=\"makemake\"\u003eMakemake\u003c/h1\u003e')\n\nconsole.log(String(file))\n```\n\nYields:\n\n```html\n\u003ch1 id=\"makemake\"\u003e\u003ca aria-hidden=\"true\" tabindex=\"-1\" href=\"#makemake\"\u003e\u003csvg height=\"10\" width=\"10\"\u003e\u003ccircle cx=\"5\" cy=\"5\" r=\"5\" fill=\"black\"\u003e\u003c/circle\u003e\u003c/svg\u003e\u003c/a\u003eMakemake\u003c/h1\u003e\n```\n\n### Example: group\n\nThe following example passes `group` as a function, to dynamically generate a\ndiffering element that wraps the heading.\nIt uses [`hastscript`][hastscript] to build nodes.\n\n```js\nimport {h} from 'hastscript'\nimport {rehype} from 'rehype'\nimport rehypeAutolinkHeadings from 'rehype-autolink-headings'\n\nconst file = await rehype()\n  .data('settings', {fragment: true})\n  .use(rehypeAutolinkHeadings, {\n    behavior: 'before',\n    group(node) {\n      return h('.heading-' + node.tagName.charAt(1) + '-group')\n    }\n  })\n  .process('\u003ch1 id=\"ceres\"\u003eCeres\u003c/h1\u003e')\n\nconsole.log(String(file))\n```\n\nYields:\n\n```html\n\u003cdiv class=\"heading-1-group\"\u003e\u003ca href=\"#ceres\"\u003e\u003cspan class=\"icon icon-link\"\u003e\u003c/span\u003e\u003c/a\u003e\u003ch1 id=\"ceres\"\u003eCeres\u003c/h1\u003e\u003c/div\u003e\n```\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional types\n[`Behavior`][api-behavior],\n[`Build`][api-build],\n[`BuildProperties`][api-build-properties], and\n[`Options`][api-options].\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line,\n`rehype-autolink-headings@^7`, compatible with Node.js 16.\n\nThis plugin works with `rehype-parse` version 1+, `rehype-stringify` version 1+,\n`rehype` version 1+, and `unified` version 4+.\n\n## Security\n\nUse of `rehype-autolink-headings` can open you up to a\n[cross-site scripting (XSS)][xss] attack if you pass user provided content in\n`content`, `group`, or `properties`.\n\nAlways be wary of user input and use [`rehype-sanitize`][rehype-sanitize].\n\n## Related\n\n* [`rehype-slug`][rehype-slug]\n  — add `id`s to headings\n* [`rehype-highlight`](https://github.com/rehypejs/rehype-highlight)\n  — apply syntax highlighting to code blocks\n* [`rehype-toc`](https://github.com/JS-DevTools/rehype-toc)\n  — add a table of contents (TOC)\n\n## Contribute\n\nSee [`contributing.md`][contributing] in [`rehypejs/.github`][health] for ways\nto get started.\nSee [`support.md`][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][license] © [Titus Wormer][author]\n\n\u003c!-- Definitions --\u003e\n\n[build-badge]: https://github.com/rehypejs/rehype-autolink-headings/workflows/main/badge.svg\n\n[build]: https://github.com/rehypejs/rehype-autolink-headings/actions\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/rehypejs/rehype-autolink-headings.svg\n\n[coverage]: https://codecov.io/github/rehypejs/rehype-autolink-headings\n\n[downloads-badge]: https://img.shields.io/npm/dm/rehype-autolink-headings.svg\n\n[downloads]: https://www.npmjs.com/package/rehype-autolink-headings\n\n[size-badge]: https://img.shields.io/bundlejs/size/rehype-autolink-headings\n\n[size]: https://bundlejs.com/?q=rehype-autolink-headings\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[collective]: https://opencollective.com/unified\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[chat]: https://github.com/rehypejs/rehype/discussions\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[health]: https://github.com/rehypejs/.github\n\n[contributing]: https://github.com/rehypejs/.github/blob/main/contributing.md\n\n[support]: https://github.com/rehypejs/.github/blob/main/support.md\n\n[coc]: https://github.com/rehypejs/.github/blob/main/code-of-conduct.md\n\n[license]: license\n\n[author]: https://wooorm.com\n\n[hast-element]: https://github.com/syntax-tree/hast#element\n\n[hast-node]: https://github.com/syntax-tree/hast#nodes\n\n[hast-util-is-element-test]: https://github.com/syntax-tree/hast-util-is-element#test\n\n[hast-properties]: https://github.com/syntax-tree/hast#properties\n\n[hastscript]: https://github.com/syntax-tree/hastscript\n\n[hast-util-from-html-isomorphic]: https://github.com/syntax-tree/hast-util-from-html-isomorphic\n\n[rehype]: https://github.com/rehypejs/rehype\n\n[rehype-sanitize]: https://github.com/rehypejs/rehype-sanitize\n\n[typescript]: https://www.typescriptlang.org\n\n[unified]: https://github.com/unifiedjs/unified\n\n[unified-transformer]: https://github.com/unifiedjs/unified#transformer\n\n[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting\n\n[rehype-slug]: https://github.com/rehypejs/rehype-slug\n\n[api-behavior]: #behavior\n\n[api-build]: #build\n\n[api-build-properties]: #buildproperties\n\n[api-options]: #options\n\n[api-rehype-autolink-headings]: #unifieduserehypeautolinkheadings-options\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frehypejs%2Frehype-autolink-headings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frehypejs%2Frehype-autolink-headings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frehypejs%2Frehype-autolink-headings/lists"}