├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package-lock.json ├── package.json └── test ├── fixtures ├── anchors-special-chars.html ├── anchors-special-chars.md ├── basic.html ├── basic.md ├── custom-attrs-with-anchors.html ├── custom-attrs.html ├── custom-attrs.md ├── empty.html ├── full-example-custom-container.html ├── full-example-list-attrs.html ├── full-example.html ├── full-example.md ├── multi-level-1234.html ├── multi-level-23.html ├── multi-level.md ├── omit.html ├── omit.md ├── simple-1-level.html ├── simple-default.html ├── simple-with-anchors.html ├── simple-with-duplicate-headings.html ├── simple-with-duplicate-headings.md ├── simple-with-header-footer.html ├── simple-with-heading-links.html ├── simple-with-heading-links.md ├── simple-with-markdown-formatting.html ├── simple-with-markdown-formatting.md ├── simple-with-transform-link.html ├── simple.md ├── strange-order.html └── strange-order.md └── modules └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | .DS_Store 29 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.9.0] - 2025-01-21 10 | 11 | * **Added:** Headlines can now be omitted from the table of contents by placing a special HTML comment tag before the headline (fixes #65). 12 | * **Added:** Option `omitTag` can override the default tag `` 13 | 14 | *** 15 | 16 | ## [0.8.0] - 2024-09-10 17 | 18 | * **Added:** Option `getTokensText` to override how text is extracted from tokens to build headlines and slugs (fixes #61), similar to the function in [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor). 19 | 20 | *** 21 | 22 | ## [0.7.0] - 2024-09-09 23 | 24 | * **Added:** Override the container element 25 | * ⚠️ **BREAKING CHANGE:** The plugin moved from *inline mode* to *block mode* (fixes #62) 26 | * **Changed:** Updated tests, readme etc. 27 | * **Removed:** Old forceFullToc attribute 28 | 29 | *** 30 | 31 | ## Override the container element 32 | 33 | Two new options that accept functions that return HTML to render custom containers (and more elements if necessary): 34 | 35 | ```js 36 | md.use(markdownItTOC, { 37 | transformContainerOpen: () => { 38 | return ''; 42 | } 43 | }); 44 | ``` 45 | 46 | ## Inline mode is now block mode 47 | 48 | Input: 49 | 50 | ```md 51 | [[toc]] 52 | ``` 53 | 54 | **Output before:** 55 | 56 | ```html 57 |
58 | ``` 59 | 60 | **Output now:** 61 | 62 | ```html 63 | 64 | ``` 65 | 66 | The TOC now is generated in block mode, which removes the wrapping `p` tag. Wrapping a `div` in a `p` is considered invalid HTML. 67 | 68 | If you really need a wrapping p-element, you can emulate the old behavior with the new container override functions: 69 | 70 | ```js 71 | const md = new MarkdownIt(); 72 | md.use(markdownItTOC, { 73 | transformContainerOpen: () => { 74 | return 'Text with soft line break (two spaces)
99 |
Text with soft line break (two spaces)
107 |Some nice text
52 | 53 |Some even nicer text
55 | ``` 56 | 57 | ## Options 58 | 59 | You may specify options when `use`ing the plugin. like so: 60 | 61 | ```js 62 | md.use(require("markdown-it-table-of-contents"), options); 63 | ``` 64 | 65 | These options are available: 66 | 67 | Name | Description | Default 68 | -----------------------|-------------------------------------------------------------------------------------|------------------------------------ 69 | `includeLevel` | Headings levels to use (2 for h2:s etc) | [1, 2] 70 | `containerClass` | The class for the container DIV | "table-of-contents" 71 | `slugify` | A custom slugification function | `encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, '-'))` 72 | `markerPattern` | Regex pattern of the marker to be replaced with TOC | `/^\[\[toc\]\]/im` 73 | `omitTag` | HTML comment tag to exclude next headline from TOC | `` 74 | `listType` | Type of list (`ul` for unordered, `ol` for ordered) | `ul` 75 | `format` | A function for formatting headings (see below) | `md.renderInline(content)` 76 | `containerHeaderHtml` | Optional HTML string for container header | `undefined` 77 | `containerFooterHtml` | Optional HTML string for container footer | `undefined` 78 | `transformLink` | A function for transforming the TOC links | `undefined` 79 | `transformContainerOpen`| A function for transforming the container opening tag | (see source code) 80 | `transformContainerClose`| A function for transforming the container closing tag | (see source code) 81 | `getTokensText` | A function for extracting text from tokens for titles | (see source code) 82 | 83 | `format` is an optional function for changing how the headings are displayed in the TOC. 84 | 85 | By default, TOC headings will be formatted using markdown-it's internal MD formatting rules (i.e. it will be formatted using the same rules / extensions as other markdown in your document). You can override this behavior by specifying a custom `format` function. The function should accept two arguments: 86 | 87 | 1. `content` - The heading test, as a markdown string. 88 | 2. `md` – markdown-it's internal markdown parser object. This should only be need for advanced use cases. 89 | 90 | ```js 91 | function format(content, md) { 92 | // manipulate the headings as you like here. 93 | return manipulatedHeadingString; 94 | } 95 | ``` 96 | 97 | `transformLink` is an optional function for transform the link as you like. 98 | 99 | ```js 100 | function transformLink(link) { 101 | // transform the link as you like here. 102 | return transformedLink; 103 | } 104 | ``` 105 | 106 | `transformContainerOpen` and `transformContainerClose` can be used to replace the container element with one or several more like so: 107 | 108 | ```js 109 | md.use(markdownItTOC, { 110 | transformContainerOpen: () => { 111 | return ''; 115 | } 116 | }); 117 | ``` 118 | 119 | `getTokensText` is a function that can be used to change how text is extracted from tokens to support more ways how headlines are build. See source code for more information or the equivalent function in [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor). 120 | 121 | ## Recommended plugins 122 | 123 | By default, markdown-it-table-of-contents collects all headings and renders a nested list. It uses the `slugify()` function to create anchor targets for the links in the list. However, the headlines in your markdown document are not touched by markdown-it-table-of-contents. You'd have a nice table of contents, but the links don't link to anything. That's why you need another plugin to generate ids (anchor link targets) for all of your headlines. There are two recommended plugins to achieve this: 124 | 125 | ### [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor) 126 | 127 | This plugin transforms all headlines in a markdown document so that the HTML code includes an id. It *slugifies* the headline: 128 | 129 | ```markdown 130 | ## Hello world, I think you should read this article 131 | ``` 132 | 133 | Becomes 134 | 135 | ```html 136 |194 |
Ad
216 |Lorem ipsum
218 |Read this next...
220 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 |Let's test special characters
10 | -------------------------------------------------------------------------------- /test/fixtures/anchors-special-chars.md: -------------------------------------------------------------------------------- 1 | # An article 2 | some text with soft break before toc 3 | [[toc]] 4 | 5 | ## Sub heading 1 6 | Some nice text 7 | 8 | ## Sub heading 2 9 | Some even nicer text 10 | 11 | ## 3.2. Test / with; special characters 12 | Let's test special characters -------------------------------------------------------------------------------- /test/fixtures/basic.html: -------------------------------------------------------------------------------- 1 |some text with hard break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/basic.md: -------------------------------------------------------------------------------- 1 | # An article 2 | some text with hard break before toc 3 | 4 | [[toc]] 5 | 6 | ## Sub heading 1 7 | Some nice text 8 | 9 | ## Sub heading 2 10 | Some even nicer text 11 | -------------------------------------------------------------------------------- /test/fixtures/custom-attrs-with-anchors.html: -------------------------------------------------------------------------------- 1 |Using custom heading id attributes via markdown-it-attrs.
3 | 4 |Note the anchor targets for TOC links.
6 |The headline above falls back to the slugify function as anchor target.
8 | -------------------------------------------------------------------------------- /test/fixtures/custom-attrs.html: -------------------------------------------------------------------------------- 1 |Using custom heading id attributes via markdown-it-attrs.
3 | 4 |Note the anchor targets for TOC links.
6 |The headline above falls back to the slugify function as anchor target.
8 | -------------------------------------------------------------------------------- /test/fixtures/custom-attrs.md: -------------------------------------------------------------------------------- 1 | # Article {#my-article} 2 | 3 | Using custom heading id attributes via markdown-it-attrs. 4 | 5 | [[toc]] 6 | 7 | ## Welcome to the show {#section-1} 8 | 9 | Note the anchor targets for TOC links. 10 | 11 | ## This has no custom id 12 | 13 | The headline above falls back to the slugify function as anchor target. 14 | -------------------------------------------------------------------------------- /test/fixtures/empty.html: -------------------------------------------------------------------------------- 1 |Ad
5 |Lorem ipsum
7 |Read this next...
9 |Ad
5 |Lorem ipsum
7 |Read this next...
9 |Ad
5 |Lorem ipsum
7 |Read this next...
9 |Next headline is two levels deeper
10 |Next headline is two levels deeper
10 |some text with hard break before toc
4 | 5 |Some nice text
7 |Some even nicer text
9 | 10 |Ignore this heading in TOC
12 |More text
14 | -------------------------------------------------------------------------------- /test/fixtures/omit.md: -------------------------------------------------------------------------------- 1 | 2 | # An article 3 | some text with hard break before toc 4 | 5 | [[toc]] 6 | 7 | ## Sub heading 1 8 | Some nice text 9 | 10 | ## Sub heading 2 11 | Some even nicer text 12 | 13 | 14 | ## Sub heading 3 15 | Ignore this heading in TOC 16 | 17 | # Next h1 Section 18 | More text -------------------------------------------------------------------------------- /test/fixtures/simple-1-level.html: -------------------------------------------------------------------------------- 1 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/simple-default.html: -------------------------------------------------------------------------------- 1 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-anchors.html: -------------------------------------------------------------------------------- 1 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-duplicate-headings.html: -------------------------------------------------------------------------------- 1 |Some nice text
5 |Some very nice text
7 |Some exceptionally nice text
9 |Some exceptionally nice text
11 |Some even nicer text
13 |Some more nice text
15 |Some exceptionally nice text
17 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-duplicate-headings.md: -------------------------------------------------------------------------------- 1 | # An article 2 | 3 | [[toc]] 4 | 5 | ## Sub heading 6 | Some nice text 7 | 8 | ### Common sub heading 9 | Some very nice text 10 | 11 | #### Duplicate heading 12 | Some exceptionally nice text 13 | 14 | #### Duplicate heading 15 | Some exceptionally nice text 16 | 17 | ## Sub heading 2 18 | Some even nicer text 19 | 20 | ### Common sub heading 21 | Some more nice text 22 | 23 | ## Duplicate heading 24 | Some exceptionally nice text 25 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-header-footer.html: -------------------------------------------------------------------------------- 1 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-heading-links.html: -------------------------------------------------------------------------------- 1 |Some nice text
5 |Some even nicer text
7 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-heading-links.md: -------------------------------------------------------------------------------- 1 | # An article 2 | 3 | [[toc]] 4 | 5 | ## [Sub heading 1](http://www.test.com) 6 | Some nice text 7 | 8 | ## Sub [heading](http://www.test.com) 2 9 | Some even nicer text 10 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-markdown-formatting.html: -------------------------------------------------------------------------------- 1 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-markdown-formatting.md: -------------------------------------------------------------------------------- 1 | # An article 2 | some text with soft break before toc 3 | [[toc]] 4 | 5 | ## Sub heading with **bold** text 6 | Some nice text 7 | 8 | ## Sub heading 2 with _italics_ text 9 | Some even nicer text 10 | -------------------------------------------------------------------------------- /test/fixtures/simple-with-transform-link.html: -------------------------------------------------------------------------------- 1 |some text with soft break before toc
3 | 4 |Some nice text
6 |Some even nicer text
8 | -------------------------------------------------------------------------------- /test/fixtures/simple.md: -------------------------------------------------------------------------------- 1 | # An article 2 | some text with soft break before toc 3 | [[toc]] 4 | 5 | ## Sub heading 1 6 | Some nice text 7 | 8 | ## Sub heading 2 9 | Some even nicer text 10 | -------------------------------------------------------------------------------- /test/fixtures/strange-order.html: -------------------------------------------------------------------------------- 1 |code
em