GithubHelp home page GithubHelp logo

isabella232 / remark-toc Goto Github PK

View Code? Open in Web Editor NEW

This project forked from remarkjs/remark-toc

0.0 0.0 0.0 205 KB

plugin to generate a table of contents (TOC)

Home Page: https://remark.js.org

License: MIT License

JavaScript 100.00%

remark-toc's Introduction

remark-toc

Build Coverage Downloads Size Sponsors Backers Chat

remark plugin to generate a table of contents.

Contents

What is this?

This package is a unified (remark) plugin to generate a table of contents of the document such as the one above.

unified is a project that transforms content with abstract syntax trees (ASTs). remark adds support for markdown to unified. mdast is the markdown AST that remark uses. This is a remark plugin that transforms mdast.

When should I use this?

This project is useful when authors are writing docs in markdown that are sometimes quite long and hence would benefit from automated overviews inside them. It is assumed that headings define the structure of documents and that they can be linked to. When this plugin is used, authors can add a certain heading (say, ## Contents) to documents and this plugin will populate those sections with lists that link to all following sections.

GitHub and similar services automatically add IDs (and anchors that link-to-self) to headings. You can add similar features when combining remark with rehype through remark-rehype after this plugin. Then it’s possible to use the rehype plugins rehype-slug (for IDs on headings) and rehype-autolink-headings (for anchors that link-to-self).

This plugin does not generate a table of contents for the whole document or expose it to other plugins. You can use the underlying mdast utility mdast-util-toc and create a plugin yourself to do that and more.

Install

This package is ESM only. In Node.js (version 12.20+, 14.14+, or 16.0+), install with npm:

npm install remark-toc

In Deno with esm.sh:

import remarkToc from 'https://esm.sh/remark-toc@8'

In browsers with esm.sh:

<script type="module">
  import remarkToc from 'https://esm.sh/remark-toc@8?bundle'
</script>

Use

Say we have the following file, example.md:

# Alpha

## Table of contents

## Bravo

### Charlie

## Delta

And our module, example.js, looks as follows:

import {read} from 'to-vfile'
import {remark} from 'remark'
import remarkToc from 'remark-toc'

main()

async function main() {
  const file = await remark()
    .use(remarkToc)
    .process(await read('example.md'))

  console.log(String(file))
}

Now, running node example yields:

# Alpha

## Table of contents

*   [Bravo](#bravo)

    *   [Charlie](#charlie)

*   [Delta](#delta)

## Bravo

### Charlie

## Delta

API

This package exports no identifiers. The default export is remarkToc.

unified().use(remarkToc[, options])

Generate a table of contents. Looks for a certain heading, removes everything between it and an equal or higher heading, and replaces that with a list representing the document structure, linking to all further headings.

options

Configuration (optional).

options.heading

Pattern text of heading to look for (string, default: 'toc|table[ -]of[ -]contents?'). Wrapped in new RegExp('^(' + options.heading + ')$', 'i'), so it’s case-insensitive and matches the whole heading text.

options.skip

Pattern text of headings to exclude from the generated list (string, optional). Wrapped in new RegExp('^(' + options.skip + ')$', 'i'), so it’s case-insensitive and matches whole heading texts.

options.maxDepth

Maximum heading depth to include in the generated list (number?, default: 6). This is inclusive: when set to 3, headings with a rank of 3 are included (those with three hashes: ###).

options.tight

Whether to compile list items tightly (boolean?, default: false). The default is to add space around items.

options.ordered

Whether to compile list items as an ordered list (boolean?, default: false). The default is to use an unordered list.

options.prefix

String to prepend before links to headings (string?, default: null, example: 'user-content-'). This is useful when combining remark with rehype through remark-rehype after this plugin, and using rehype-sanitize to prevent DOM clobbering of user generated markdown.

options.parents

Parents (such as block quotes and lists) of headings to include in the generated list (is-compatible test, default: the root node). By default only top level headings are used. Pass ['root', 'blockquote'] to also link to headings in block quotes.

Examples

Example: a different heading

The option heading can be set to search for a different heading. The example from before can be changed to search for different headings like so:

@@ -6,7 +6,7 @@ main()

 async function main() {
   const file = await remark()
-    .use(remarkToc)
+    .use(remarkToc, {heading: 'contents'})
     .process(await read('example.md'))

   console.log(String(file))

…that would search for Contents (case-insensitive) headings.

Example: ordered, tight list

The options ordered and tight can be turned on to change the list. The example from before can be changed to generate a tight, ordered list like so:

@@ -6,7 +6,10 @@ main()

 async function main() {
   const file = await remark()
-    .use(remarkToc)
+    .use(remarkToc, {tight: true, ordered: true})
     .process(await read('example.md'))

   console.log(String(file))

…that would generate the following list:

1.  [Bravo](#bravo)
    1.  [Charlie](#charlie)
2.  [Delta](#delta)

Example: including and excluding headings

The options maxDepth, skip, and parents can be used to include and exclude certain headings from list. The example from before can be changed to generate a tight, ordered list like so:

@@ -6,7 +6,10 @@ main()

 async function main() {
   const file = await remark()
-    .use(remarkToc)
+    .use(remarkToc, {maxDepth: 3, skip: 'delta', parents: ['root', 'listItem']})
     .process(await read('example.md'))

   console.log(String(file))

…that would exclude level 4, 5, and 6 headings, exclude headings of delta (case-insensitive, full match), and include headings directly in a list item.

Example: adding a prefix

The option prefix can set to prepend a string to all links to headings in the generated list:

@@ -6,7 +6,10 @@ main()

 async function main() {
   const file = await remark()
-    .use(remarkToc)
+    .use(remarkToc, {prefix: 'user-content-'})
     .process(await read('example.md'))

   console.log(String(file))

…that would generate the following list:

*   [Bravo](#user-content-bravo)

    *   [Charlie](#user-content-charlie)

*   [Delta](#user-content-delta)

Types

This package is fully typed with TypeScript. It exports an Options type, which specifies the interface 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 unified version 3+ and remark version 4+.

Security

Use of remark-toc involves user content and changes the tree, so it can open you up for a cross-site scripting (XSS) attack.

Existing nodes are copied into the table of contents. The following example shows how an existing script is copied into the table of contents.

The following markdown:

# Table of Contents

## Bravo<script>alert(1)</script>

## Charlie

Yields:

# Table of Contents

-   [Bravo<script>alert(1)</script>](#bravoscriptalert1script)
-   [Charlie](#charlie)

## Bravo<script>alert(1)</script>

## Charlie

This may become a problem if the markdown is later transformed to rehype (hast) or opened in an unsafe markdown viewer.

Related

Contribute

See contributing.md in remarkjs/.github for ways to get started. See support.md for ways to get help.

This project has a code of conduct. By interacting with this repository, organization, or community you agree to abide by its terms.

License

MIT © Titus Wormer

remark-toc's People

Contributors

babie avatar barrythepenguin avatar gkatsev avatar greenkeeperio-bot avatar millette avatar teinett avatar wooorm avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.