npm package: @frat/markdown-toc
Description: Generate a markdown TOC (table of contents) with Remarkable.
Latest version: 1.3.0

# @frat/markdown-toc

> Generate a markdown TOC (table of contents) with Remarkable.

Please consider starring the project to show your :heart: and support.

- [Highlights](#highlights)
- [Usage](#usage)
- [API](#api)
  - [toc.plugin](#tocplugin)
  - [toc.json](#tocjson)
  - [toc.insert](#tocinsert)
  - [Utility functions](#utility-functions)
- [Options](#options)
  - [options.append](#optionsappend)
  - [options.filter](#optionsfilter)
  - [options.slugify](#optionsslugify)
  - [options.bullets](#optionsbullets)
  - [options.maxdepth](#optionsmaxdepth)
  - [options.firsth1](#optionsfirsth1)
  - [options.stripHeadingTags](#optionsstripheadingtags)
- [About](#about)

## Install

Install with [npm](https://www.npmjs.com/)

Install to your global set of commands:

```sh
npm install -g @frat/markdown-toc
```

Install to your local npm project:

```sh
npm install --save @frat/markdown-toc
```

## Quick Start

Assuming you want to add a TOC to README.md:

1. `$ npm install -g @frat/markdown-toc`
2. Edit README.md and insert the following line where you want the TOC inserted:<br />`<!-- toc -->`
3. `$ markdown-toc -i README.md`

## CLI

```
Usage: markdown-toc [options] <input>

  input:        The Markdown file to parse for table of contents,
                or "-" to read from stdin.

  -i:           Edit the <input> file directly, injecting the TOC at - [Highlights](#highlights)
                (Without this flag, the default is to print the TOC to stdout.)

  --json:       Print the TOC in JSON format

  --append:     Append a string to the end of the TOC

  --bullets:    Bullets to use for items in the generated TOC
                (Supports multiple bullets: --bullets "*" --bullets "-" --bullets "+")
                (Default is "*".)

  --maxdepth:   Use headings whose depth is at most maxdepth
                (Default is 6.)

  --no-firsth1: Include the first h1-level heading in a file

  --no-stripHeadingTags: Do not strip extraneous HTML tags from heading
                         text before slugifying

  --indent:     Provide the indentation to use - defaults to '  '
                (to specify a tab, use the bash-escaped $'\t')

  --version:    Print version
```

## Highlights

This is a fork of [markdown-doc](https://www.npmjs.com/package/markdown-toc) with the following differences,

- Updated dependencies
- Merged PR
  [96](https://github.com/jonschlinkert/markdown-toc/pull/96),
  [157](https://github.com/jonschlinkert/markdown-toc/pull/157),
  [191](https://github.com/jonschlinkert/markdown-toc/pull/191)
- Add `--version` flag

**Features**

- Can optionally be used as a [remarkable](https://github.com/jonschlinkert/remarkable) plugin
- Returns an object with the rendered TOC (on `content`), as well as a `json` property with the raw TOC object, so you can generate your own TOC using templates or however you want
- Works with [repeated headings](https://gist.github.com/jonschlinkert/ac5d8122bfaaa394f896)
- Uses sane defaults, so no customization is necessary, but you can if you need to.
- [filter](#filter-headings) out headings you don't want
- [Improve](#titleize) the headings you do want
- Use a custom [slugify](#optionsslugify) function to change how links are created

**Safe!**

- Won't mangle markdown in code examples in gfm code blocks that other TOC generators mistake as being actual headings (this happens when markdown headings are show in _examples_, meaning they aren't actually headings that should be in the toc. Also happens with yaml and coffee-script comments, or any comments that use `#`)
- Won't mangle front-matter, or mistake front-matter properties for headings like other TOC generators

## Usage

```js
var toc = require("markdown-toc");

toc("# One\n\n# Two").content;
// Results in:
// - [One](#one)
// - [Two](#two)
```

To allow customization of the output, an object is returned with the following properties:

- `content` **{String}**: The generated table of contents. Unless you want to customize rendering, this is all you need.
- `highest` **{Number}**: The highest level heading found. This is used to adjust indentation.
- `tokens` **{Array}**: Headings tokens that can be used for custom rendering

## API

### toc.plugin

Use as a [remarkable](https://github.com/jonschlinkert/remarkable) plugin.

```js
var Remarkable = require("remarkable");
var toc = require("markdown-toc");

function render(str, options) {
  return new Remarkable()
    .use(toc.plugin(options)) // <= register the plugin
    .render(str);
}
```

**Usage example**

```js
var results = render("# AAA\n# BBB\n# CCC\nfoo\nbar\nbaz");
```

Results in:

```
- [AAA](#aaa)
- [BBB](#bbb)
- [CCC](#ccc)
```

### toc.json

Object for creating a custom TOC.

```js
toc("# AAA\n## BBB\n### CCC\nfoo").json;

// results in
[
  { content: "AAA", slug: "aaa", lvl: 1 },
  { content: "BBB", slug: "bbb", lvl: 2 },
  { content: "CCC", slug: "ccc", lvl: 3 },
];
```

### toc.insert

Insert a table of contents immediately after an _opening_ `<!-- toc -->` code comment, or replace an existing TOC if both an _opening_ comment and a _closing_ comment (`<!-- tocstop -->`) are found.

_(This strategy works well since code comments in markdown are hidden when viewed as HTML, like when viewing a README on GitHub README for example)._

**Example**

```
<!-- toc -->
- old toc 1
- old toc 2
- old toc 3
<!-- tocstop -->

## abc
This is a b c.

## xyz
This is x y z.
```

Would result in something like:

```
<!-- toc -->
- [abc](#abc)
- [xyz](#xyz)
<!-- tocstop -->

## abc
This is a b c.

## xyz
This is x y z.
```

### Utility functions

As a convenience to folks who wants to create a custom TOC, markdown-toc's internal utility methods are exposed:

```js
var toc = require("markdown-toc");
```

- `toc.bullets()`: render a bullet list from an array of tokens
- `toc.linkify()`: linking a heading `content` string
- `toc.slugify()`: slugify a heading `content` string
- `toc.strip()`: strip words or characters from a heading `content` string

**Example**

```js
var result = toc("# AAA\n## BBB\n### CCC\nfoo");
var str = "";

result.json.forEach(function (heading) {
  str += toc.linkify(heading.content);
});
```

## Options

### options.append

Append a string to the end of the TOC.

```js
toc(str, { append: "\n_(TOC generated by Verb)_" });
```

### options.filter

Type: `Function`

Default: `undefined`

Params:

- `str` **{String}** the actual heading string
- `ele` **{Objecct}** object of heading tokens
- `arr` **{Array}** all of the headings objects

**Example**

From time to time, we might get junk like this in our TOC.

```
[.aaa([foo], ...) another bad heading](#-aaa--foo--------another-bad-heading)
```

Unless you like that kind of thing, you might want to filter these bad headings out.

```js
function removeJunk(str, ele, arr) {
  return str.indexOf("...") === -1;
}

var result = toc(str, { filter: removeJunk });
//=> beautiful TOC
```

### options.slugify

Type: `Function`

Default: Basic non-word character replacement.

**Example**

```js
var str = toc("# Some Article", { slugify: require("uslug") });
```

### options.bullets

Type: `String|Array`

Default: `*`

The bullet to use for each item in the generated TOC. If passed as an array (`['*', '-', '+']`), the bullet point strings will be used based on the header depth.

### options.maxdepth

Type: `Number`

Default: `6`

Use headings whose depth is at most maxdepth.

### options.firsth1

Type: `Boolean`

Default: `true`

Exclude the first h1-level heading in a file. For example, this prevents the first heading in a README from showing up in the TOC.

### options.stripHeadingTags

Type: `Boolean`

Default: `true`

Strip extraneous HTML tags from heading text before slugifying. This is similar to GitHub markdown behavior.

## About

<details>
<summary><strong>Contributing</strong></summary>

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

</details>

<details>
<summary><strong>Running Tests</strong></summary>

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
npm install && npm test
```

</details>

### License

Copyright © 2024, [Ratson](https://github.com/ratson).
Copyright © 2023, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).