From f5ed946e92f423c7a3669dca2a212fc662111709 Mon Sep 17 00:00:00 2001 From: Tim Scanlin Date: Wed, 15 Jan 2025 19:43:59 -0800 Subject: [PATCH 1/5] add section for sponsors --- README.md | 14 ++++++++++++++ data/README.json | 4 ++-- static/img/getsentry.png | Bin 0 -> 22218 bytes static/img/roboflow.png | Bin 0 -> 10496 bytes 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 static/img/getsentry.png create mode 100644 static/img/roboflow.png diff --git a/README.md b/README.md index 3300dc6d..2d243286 100644 --- a/README.md +++ b/README.md @@ -287,6 +287,20 @@ tocbot.refresh() - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add. - If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330). +## Sponsors + +If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you! + +Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors! + +![Roboflow](https://github.com/tscanlin/tocbot/blob/master/static/img/roboflow.png) +
+Roboflow + +![GetSentry](https://github.com/tscanlin/tocbot/blob/master/static/img/getsentry.png) +
+Get Sentry + ## Contributing Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion. diff --git a/data/README.json b/data/README.json index 31c31333..82059591 100644 --- a/data/README.json +++ b/data/README.json @@ -1,6 +1,6 @@ { - "bodyContent": "

\nTocbot\n

\n\n\"github-actions\"\n\"cdnjs\"\n\"GitHub\n\nTocbot builds a [table of contents](https://en.wikipedia.org/wiki/Table_of_contents) (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by [Tocify](http://gregfranko.com/jquery.tocify.js/), the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.\n\n\n## Get Started\n\nYou can use npm to install it or include the script on the page with HTML.\n\n[**Download it here**](https://github.com/tscanlin/tocbot/releases/)\n\n\n### Include JS\n\nInstall it with npm.\n\n```sh\nnpm install --save tocbot\n```\n\nThen use with either commonjs or ESM imports:\n\n```js\nconst tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()\n```\n\nOR\n\nInclude the script at the bottom of the page before the closing body tag.\n\n```html\n\n```\n\n\n### Include CSS\n\nCSS is used for expanding & collapsing groupings and some basic styling.\n\n```html\n\n```\n\nOR\n\nIf you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', [see the includePath option documentation for more info](https://github.com/sass/node-sass#includepaths)\n\n```scss\n@import 'tocbot/src/scss/tocbot';\n```\n\n\n### Usage\n\nInitialize the script at the bottom of the page before the closing body tag.\n\n```js\ntocbot.init({\n // Where to render the table of contents.\n tocSelector: '.js-toc',\n // Where to grab the headings to build the table of contents.\n contentSelector: '.js-toc-content',\n // Which headings to grab inside of the contentSelector element.\n headingSelector: 'h1, h2, h3',\n // For headings inside relative or absolute positioned containers within content.\n hasInnerContainers: true,\n});\n```\n\n**NOTE:** Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this for you.\n\nIf content in the div has changed then trigger a refresh (optionally with new options).\n\n```javascript\ntocbot.refresh();\n```\n\nAlso you can use it within typescript:\n\n```typescript\nimport * as tocbot from 'tocbot';\n\ntocbot.init({\n // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();\n```\n\n## Examples\n\n- [Tocbot Homepage](https://tscanlin.github.io/tocbot/)\n- [Storybook uses Tocbot](https://storybook.js.org/docs/writing-docs/autodocs#configure-the-table-of-contents)\n - Tocbot is used under the hood in storybook to provide TOC generation for component docs in storybook.\n\nIf you'd like to add your page to this list open a pull request.\n\n\n## Requirements\n\nThis library uses **vanilla JavaScript**. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.\n\nThis script works in **all modern browsers and IE 9+**.\n\n**Make sure rendered headings have id attributes**, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this. If you need to do this client side see [this script](https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js).\n\n**NOTE:** to exclude anchor elements from smooth scrolling, add the class `no-smooth-scroll`.\n\n\n### Fixed headers\n\nTo handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a `40px` tall fixed header would be:\n\n```js\ntocbot.init({\n headingsOffset: 40,\n scrollSmoothOffset: -40\n})\n```\n\n\n## API\n\n### Options\n\n```javascript\n// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false\n```\n\n\n### Methods\n\n#### .init\n\nInitialize tocbot with an options object.\n\n```javascript\ntocbot.init(options)\n```\n\n#### .destroy\n\nDestroy tocbot and remove event listeners.\n\n```javascript\ntocbot.destroy()\n```\n\n#### .refresh\n\nRefresh tocbot if the document changes and it needs to be rebuilt.\n\n```javascript\ntocbot.refresh()\n```\n\n\n## Troubleshooting\n\n- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add.\n- If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330).\n\n## Contributing\n\nContributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.\n\nIf you want to open a pull request just fork the repo but please make sure all tests and lint pass.\n\n\n### Running Tests\n\n```bash\nnpm run test\n```\n\n### Steps to publish\n\n- Push a branch and open a pull request\n- run `npm version `\n- Update readme.md with notes\n- Merge the pull request\n- commit dist/\n- run `npm publish`\n- make release on github\n\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)", - "bodyHtml": "

\nTocbot\n

\n

\"github-actions\"\n\"cdnjs\"\n\"GitHub

\n

Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.

\n

Get Started

\n

You can use npm to install it or include the script on the page with HTML.

\n

Download it here

\n

Include JS

\n

Install it with npm.

\n
npm install --save tocbot

Then use with either commonjs or ESM imports:

\n
const tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()

OR

\n

Include the script at the bottom of the page before the closing body tag.

\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.min.js"></script>

Include CSS

\n

CSS is used for expanding & collapsing groupings and some basic styling.

\n
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.css">

OR

\n

If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info

\n
@import 'tocbot/src/scss/tocbot';

Usage

\n

Initialize the script at the bottom of the page before the closing body tag.

\n
tocbot.init({\n  // Where to render the table of contents.\n  tocSelector: '.js-toc',\n  // Where to grab the headings to build the table of contents.\n  contentSelector: '.js-toc-content',\n  // Which headings to grab inside of the contentSelector element.\n  headingSelector: 'h1, h2, h3',\n  // For headings inside relative or absolute positioned containers within content.\n  hasInnerContainers: true,\n});

NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading, some markdown libraries (like marked) already do this for you.

\n

If content in the div has changed then trigger a refresh (optionally with new options).

\n
tocbot.refresh();

Also you can use it within typescript:

\n
import * as tocbot from 'tocbot';\n\ntocbot.init({\n  // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();

Examples

\n\n

If you'd like to add your page to this list open a pull request.

\n

Requirements

\n

This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.

\n

This script works in all modern browsers and IE 9+.

\n

Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.

\n

NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll.

\n

Fixed headers

\n

To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px tall fixed header would be:

\n
tocbot.init({\n  headingsOffset: 40,\n  scrollSmoothOffset: -40\n})

API

\n

Options

\n
// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false

Methods

\n

.init

\n

Initialize tocbot with an options object.

\n
tocbot.init(options)

.destroy

\n

Destroy tocbot and remove event listeners.

\n
tocbot.destroy()

.refresh

\n

Refresh tocbot if the document changes and it needs to be rebuilt.

\n
tocbot.refresh()

Troubleshooting

\n\n

Contributing

\n

Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.

\n

If you want to open a pull request just fork the repo but please make sure all tests and lint pass.

\n

Running Tests

\n
npm run test

Steps to publish

\n\n

License

\n

MIT

\n", + "bodyContent": "

\nTocbot\n

\n\n\"github-actions\"\n\"cdnjs\"\n\"GitHub\n\nTocbot builds a [table of contents](https://en.wikipedia.org/wiki/Table_of_contents) (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by [Tocify](http://gregfranko.com/jquery.tocify.js/), the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.\n\n\n## Get Started\n\nYou can use npm to install it or include the script on the page with HTML.\n\n[**Download it here**](https://github.com/tscanlin/tocbot/releases/)\n\n\n### Include JS\n\nInstall it with npm.\n\n```sh\nnpm install --save tocbot\n```\n\nThen use with either commonjs or ESM imports:\n\n```js\nconst tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()\n```\n\nOR\n\nInclude the script at the bottom of the page before the closing body tag.\n\n```html\n\n```\n\n\n### Include CSS\n\nCSS is used for expanding & collapsing groupings and some basic styling.\n\n```html\n\n```\n\nOR\n\nIf you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', [see the includePath option documentation for more info](https://github.com/sass/node-sass#includepaths)\n\n```scss\n@import 'tocbot/src/scss/tocbot';\n```\n\n\n### Usage\n\nInitialize the script at the bottom of the page before the closing body tag.\n\n```js\ntocbot.init({\n // Where to render the table of contents.\n tocSelector: '.js-toc',\n // Where to grab the headings to build the table of contents.\n contentSelector: '.js-toc-content',\n // Which headings to grab inside of the contentSelector element.\n headingSelector: 'h1, h2, h3',\n // For headings inside relative or absolute positioned containers within content.\n hasInnerContainers: true,\n});\n```\n\n**NOTE:** Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: [marked](https://github.com/markedjs/marked) [can be configured to generate IDs based on patterns you define](https://github.com/markedjs/marked/issues/326#issuecomment-2567091770); [Showdown.js](https://showdownjs.com) generates IDs by default.\n\nIf content in the div has changed then trigger a refresh (optionally with new options).\n\n```javascript\ntocbot.refresh();\n```\n\nAlso you can use it within typescript:\n\n```typescript\nimport * as tocbot from 'tocbot';\n\ntocbot.init({\n // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();\n```\n\n## Examples\n\n- [Tocbot Homepage](https://tscanlin.github.io/tocbot/)\n- [Storybook uses Tocbot](https://storybook.js.org/docs/writing-docs/autodocs#configure-the-table-of-contents)\n - Tocbot is used under the hood in storybook to provide TOC generation for component docs in storybook.\n\nIf you'd like to add your page to this list open a pull request.\n\n\n## Requirements\n\nThis library uses **vanilla JavaScript**. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.\n\nThis script works in **all modern browsers and IE 9+**.\n\n**Make sure rendered headings have id attributes**, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this. If you need to do this client side see [this script](https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js).\n\n**NOTE:** to exclude anchor elements from smooth scrolling, add the class `no-smooth-scroll`.\n\n\n### Fixed headers\n\nTo handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a `40px` tall fixed header would be:\n\n```js\ntocbot.init({\n headingsOffset: 40,\n scrollSmoothOffset: -40\n})\n```\n\n\n## API\n\n### Options\n\n```javascript\n// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false\n```\n\n\n### Methods\n\n#### .init\n\nInitialize tocbot with an options object.\n\n```javascript\ntocbot.init(options)\n```\n\n#### .destroy\n\nDestroy tocbot and remove event listeners.\n\n```javascript\ntocbot.destroy()\n```\n\n#### .refresh\n\nRefresh tocbot if the document changes and it needs to be rebuilt.\n\n```javascript\ntocbot.refresh()\n```\n\n\n## Troubleshooting\n\n- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add.\n- If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330).\n\n## Sponsors\n\nIf you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the \"Sponsor\" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!\n\nSponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!\n\n![Roboflow](https://github.com/tscanlin/tocbot/blob/master/static/img/roboflow.png)\nRoboflow\n\n![GetSentry](https://github.com/tscanlin/tocbot/blob/master/static/img/getsentry.png)\nGet Sentry\n\n## Contributing\n\nContributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.\n\nIf you want to open a pull request just fork the repo but please make sure all tests and lint pass.\n\n\n### Running Tests\n\n```bash\nnpm run test\n```\n\n### Steps to publish\n\n- Push a branch and open a pull request\n- run `npm version `\n- Update readme.md with notes\n- Merge the pull request\n- commit dist/\n- run `npm publish`\n- make release on github\n\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)", + "bodyHtml": "

\nTocbot\n

\n

\"github-actions\"\n\"cdnjs\"\n\"GitHub

\n

Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.

\n

Get Started

\n

You can use npm to install it or include the script on the page with HTML.

\n

Download it here

\n

Include JS

\n

Install it with npm.

\n
npm install --save tocbot

Then use with either commonjs or ESM imports:

\n
const tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()

OR

\n

Include the script at the bottom of the page before the closing body tag.

\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.min.js"></script>

Include CSS

\n

CSS is used for expanding & collapsing groupings and some basic styling.

\n
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.css">

OR

\n

If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info

\n
@import 'tocbot/src/scss/tocbot';

Usage

\n

Initialize the script at the bottom of the page before the closing body tag.

\n
tocbot.init({\n  // Where to render the table of contents.\n  tocSelector: '.js-toc',\n  // Where to grab the headings to build the table of contents.\n  contentSelector: '.js-toc-content',\n  // Which headings to grab inside of the contentSelector element.\n  headingSelector: 'h1, h2, h3',\n  // For headings inside relative or absolute positioned containers within content.\n  hasInnerContainers: true,\n});

NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: marked can be configured to generate IDs based on patterns you define; Showdown.js generates IDs by default.

\n

If content in the div has changed then trigger a refresh (optionally with new options).

\n
tocbot.refresh();

Also you can use it within typescript:

\n
import * as tocbot from 'tocbot';\n\ntocbot.init({\n  // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();

Examples

\n\n

If you'd like to add your page to this list open a pull request.

\n

Requirements

\n

This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.

\n

This script works in all modern browsers and IE 9+.

\n

Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.

\n

NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll.

\n

Fixed headers

\n

To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px tall fixed header would be:

\n
tocbot.init({\n  headingsOffset: 40,\n  scrollSmoothOffset: -40\n})

API

\n

Options

\n
// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false

Methods

\n

.init

\n

Initialize tocbot with an options object.

\n
tocbot.init(options)

.destroy

\n

Destroy tocbot and remove event listeners.

\n
tocbot.destroy()

.refresh

\n

Refresh tocbot if the document changes and it needs to be rebuilt.

\n
tocbot.refresh()

Troubleshooting

\n
    \n
  • Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n
      \n
    • Try running this from the console: tocbot.refresh({ ...tocbot.options, hasInnerContainers: true }). If that works then one option (hasInnerContainers: true) to handle inner containers should be all you need to add.
    • \n
    \n
  • \n
  • If you have a really long TOC and are seeing headings getting truncated, then have a look at this issue for a workaround to resolve it.
  • \n
\n

Sponsors

\n

If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting the tocbot repo on github and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!

\n

Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!

\n

\"Roboflow\"\nRoboflow

\n

\"GetSentry\"\nGet Sentry

\n

Contributing

\n

Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.

\n

If you want to open a pull request just fork the repo but please make sure all tests and lint pass.

\n

Running Tests

\n
npm run test

Steps to publish

\n
    \n
  • Push a branch and open a pull request
  • \n
  • run npm version <patch|minor|major>
  • \n
  • Update readme.md with notes
  • \n
  • Merge the pull request
  • \n
  • commit dist/
  • \n
  • run npm publish
  • \n
  • make release on github
  • \n
\n

License

\n

MIT

\n", "title": "Tocbot", "dir": "data", "base": "README.json", diff --git a/static/img/getsentry.png b/static/img/getsentry.png new file mode 100644 index 0000000000000000000000000000000000000000..ab5419a90ef2b776805474d6cbd916d578703d2f GIT binary patch literal 22218 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 literal 0 HcmV?d00001 From ece48fda3747bd1686d12b5662b2057684f65697 Mon Sep 17 00:00:00 2001 From: Tim Scanlin Date: Wed, 15 Jan 2025 19:46:06 -0800 Subject: [PATCH 2/5] update img path --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d243286..3d56c848 100644 --- a/README.md +++ b/README.md @@ -293,11 +293,11 @@ If you find Tocbot useful, consider supporting it by becoming a sponsor. You can Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors! -![Roboflow](https://github.com/tscanlin/tocbot/blob/master/static/img/roboflow.png) +![Roboflow](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/roboflow.png)
Roboflow -![GetSentry](https://github.com/tscanlin/tocbot/blob/master/static/img/getsentry.png) +![GetSentry](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/getsentry.png)
Get Sentry From 7651b6948be888a94334c9b238b3caa4884d336f Mon Sep 17 00:00:00 2001 From: Tim Scanlin Date: Wed, 15 Jan 2025 19:47:01 -0800 Subject: [PATCH 3/5] run build --- data/README.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/README.json b/data/README.json index 82059591..931bda22 100644 --- a/data/README.json +++ b/data/README.json @@ -1,6 +1,6 @@ { - "bodyContent": "

\nTocbot\n

\n\n\"github-actions\"\n\"cdnjs\"\n\"GitHub\n\nTocbot builds a [table of contents](https://en.wikipedia.org/wiki/Table_of_contents) (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by [Tocify](http://gregfranko.com/jquery.tocify.js/), the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.\n\n\n## Get Started\n\nYou can use npm to install it or include the script on the page with HTML.\n\n[**Download it here**](https://github.com/tscanlin/tocbot/releases/)\n\n\n### Include JS\n\nInstall it with npm.\n\n```sh\nnpm install --save tocbot\n```\n\nThen use with either commonjs or ESM imports:\n\n```js\nconst tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()\n```\n\nOR\n\nInclude the script at the bottom of the page before the closing body tag.\n\n```html\n\n```\n\n\n### Include CSS\n\nCSS is used for expanding & collapsing groupings and some basic styling.\n\n```html\n\n```\n\nOR\n\nIf you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', [see the includePath option documentation for more info](https://github.com/sass/node-sass#includepaths)\n\n```scss\n@import 'tocbot/src/scss/tocbot';\n```\n\n\n### Usage\n\nInitialize the script at the bottom of the page before the closing body tag.\n\n```js\ntocbot.init({\n // Where to render the table of contents.\n tocSelector: '.js-toc',\n // Where to grab the headings to build the table of contents.\n contentSelector: '.js-toc-content',\n // Which headings to grab inside of the contentSelector element.\n headingSelector: 'h1, h2, h3',\n // For headings inside relative or absolute positioned containers within content.\n hasInnerContainers: true,\n});\n```\n\n**NOTE:** Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: [marked](https://github.com/markedjs/marked) [can be configured to generate IDs based on patterns you define](https://github.com/markedjs/marked/issues/326#issuecomment-2567091770); [Showdown.js](https://showdownjs.com) generates IDs by default.\n\nIf content in the div has changed then trigger a refresh (optionally with new options).\n\n```javascript\ntocbot.refresh();\n```\n\nAlso you can use it within typescript:\n\n```typescript\nimport * as tocbot from 'tocbot';\n\ntocbot.init({\n // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();\n```\n\n## Examples\n\n- [Tocbot Homepage](https://tscanlin.github.io/tocbot/)\n- [Storybook uses Tocbot](https://storybook.js.org/docs/writing-docs/autodocs#configure-the-table-of-contents)\n - Tocbot is used under the hood in storybook to provide TOC generation for component docs in storybook.\n\nIf you'd like to add your page to this list open a pull request.\n\n\n## Requirements\n\nThis library uses **vanilla JavaScript**. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.\n\nThis script works in **all modern browsers and IE 9+**.\n\n**Make sure rendered headings have id attributes**, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this. If you need to do this client side see [this script](https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js).\n\n**NOTE:** to exclude anchor elements from smooth scrolling, add the class `no-smooth-scroll`.\n\n\n### Fixed headers\n\nTo handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a `40px` tall fixed header would be:\n\n```js\ntocbot.init({\n headingsOffset: 40,\n scrollSmoothOffset: -40\n})\n```\n\n\n## API\n\n### Options\n\n```javascript\n// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false\n```\n\n\n### Methods\n\n#### .init\n\nInitialize tocbot with an options object.\n\n```javascript\ntocbot.init(options)\n```\n\n#### .destroy\n\nDestroy tocbot and remove event listeners.\n\n```javascript\ntocbot.destroy()\n```\n\n#### .refresh\n\nRefresh tocbot if the document changes and it needs to be rebuilt.\n\n```javascript\ntocbot.refresh()\n```\n\n\n## Troubleshooting\n\n- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add.\n- If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330).\n\n## Sponsors\n\nIf you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the \"Sponsor\" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!\n\nSponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!\n\n![Roboflow](https://github.com/tscanlin/tocbot/blob/master/static/img/roboflow.png)\nRoboflow\n\n![GetSentry](https://github.com/tscanlin/tocbot/blob/master/static/img/getsentry.png)\nGet Sentry\n\n## Contributing\n\nContributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.\n\nIf you want to open a pull request just fork the repo but please make sure all tests and lint pass.\n\n\n### Running Tests\n\n```bash\nnpm run test\n```\n\n### Steps to publish\n\n- Push a branch and open a pull request\n- run `npm version `\n- Update readme.md with notes\n- Merge the pull request\n- commit dist/\n- run `npm publish`\n- make release on github\n\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)", - "bodyHtml": "

\nTocbot\n

\n

\"github-actions\"\n\"cdnjs\"\n\"GitHub

\n

Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.

\n

Get Started

\n

You can use npm to install it or include the script on the page with HTML.

\n

Download it here

\n

Include JS

\n

Install it with npm.

\n
npm install --save tocbot

Then use with either commonjs or ESM imports:

\n
const tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()

OR

\n

Include the script at the bottom of the page before the closing body tag.

\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.min.js"></script>

Include CSS

\n

CSS is used for expanding & collapsing groupings and some basic styling.

\n
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.css">

OR

\n

If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info

\n
@import 'tocbot/src/scss/tocbot';

Usage

\n

Initialize the script at the bottom of the page before the closing body tag.

\n
tocbot.init({\n  // Where to render the table of contents.\n  tocSelector: '.js-toc',\n  // Where to grab the headings to build the table of contents.\n  contentSelector: '.js-toc-content',\n  // Which headings to grab inside of the contentSelector element.\n  headingSelector: 'h1, h2, h3',\n  // For headings inside relative or absolute positioned containers within content.\n  hasInnerContainers: true,\n});

NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: marked can be configured to generate IDs based on patterns you define; Showdown.js generates IDs by default.

\n

If content in the div has changed then trigger a refresh (optionally with new options).

\n
tocbot.refresh();

Also you can use it within typescript:

\n
import * as tocbot from 'tocbot';\n\ntocbot.init({\n  // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();

Examples

\n\n

If you'd like to add your page to this list open a pull request.

\n

Requirements

\n

This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.

\n

This script works in all modern browsers and IE 9+.

\n

Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.

\n

NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll.

\n

Fixed headers

\n

To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px tall fixed header would be:

\n
tocbot.init({\n  headingsOffset: 40,\n  scrollSmoothOffset: -40\n})

API

\n

Options

\n
// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false

Methods

\n

.init

\n

Initialize tocbot with an options object.

\n
tocbot.init(options)

.destroy

\n

Destroy tocbot and remove event listeners.

\n
tocbot.destroy()

.refresh

\n

Refresh tocbot if the document changes and it needs to be rebuilt.

\n
tocbot.refresh()

Troubleshooting

\n
    \n
  • Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n
      \n
    • Try running this from the console: tocbot.refresh({ ...tocbot.options, hasInnerContainers: true }). If that works then one option (hasInnerContainers: true) to handle inner containers should be all you need to add.
    • \n
    \n
  • \n
  • If you have a really long TOC and are seeing headings getting truncated, then have a look at this issue for a workaround to resolve it.
  • \n
\n

Sponsors

\n

If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting the tocbot repo on github and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!

\n

Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!

\n

\"Roboflow\"\nRoboflow

\n

\"GetSentry\"\nGet Sentry

\n

Contributing

\n

Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.

\n

If you want to open a pull request just fork the repo but please make sure all tests and lint pass.

\n

Running Tests

\n
npm run test

Steps to publish

\n
    \n
  • Push a branch and open a pull request
  • \n
  • run npm version <patch|minor|major>
  • \n
  • Update readme.md with notes
  • \n
  • Merge the pull request
  • \n
  • commit dist/
  • \n
  • run npm publish
  • \n
  • make release on github
  • \n
\n

License

\n

MIT

\n", + "bodyContent": "

\nTocbot\n

\n\n\"github-actions\"\n\"cdnjs\"\n\"GitHub\n\nTocbot builds a [table of contents](https://en.wikipedia.org/wiki/Table_of_contents) (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by [Tocify](http://gregfranko.com/jquery.tocify.js/), the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.\n\n\n## Get Started\n\nYou can use npm to install it or include the script on the page with HTML.\n\n[**Download it here**](https://github.com/tscanlin/tocbot/releases/)\n\n\n### Include JS\n\nInstall it with npm.\n\n```sh\nnpm install --save tocbot\n```\n\nThen use with either commonjs or ESM imports:\n\n```js\nconst tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()\n```\n\nOR\n\nInclude the script at the bottom of the page before the closing body tag.\n\n```html\n\n```\n\n\n### Include CSS\n\nCSS is used for expanding & collapsing groupings and some basic styling.\n\n```html\n\n```\n\nOR\n\nIf you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', [see the includePath option documentation for more info](https://github.com/sass/node-sass#includepaths)\n\n```scss\n@import 'tocbot/src/scss/tocbot';\n```\n\n\n### Usage\n\nInitialize the script at the bottom of the page before the closing body tag.\n\n```js\ntocbot.init({\n // Where to render the table of contents.\n tocSelector: '.js-toc',\n // Where to grab the headings to build the table of contents.\n contentSelector: '.js-toc-content',\n // Which headings to grab inside of the contentSelector element.\n headingSelector: 'h1, h2, h3',\n // For headings inside relative or absolute positioned containers within content.\n hasInnerContainers: true,\n});\n```\n\n**NOTE:** Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: [marked](https://github.com/markedjs/marked) [can be configured to generate IDs based on patterns you define](https://github.com/markedjs/marked/issues/326#issuecomment-2567091770); [Showdown.js](https://showdownjs.com) generates IDs by default.\n\nIf content in the div has changed then trigger a refresh (optionally with new options).\n\n```javascript\ntocbot.refresh();\n```\n\nAlso you can use it within typescript:\n\n```typescript\nimport * as tocbot from 'tocbot';\n\ntocbot.init({\n // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();\n```\n\n## Examples\n\n- [Tocbot Homepage](https://tscanlin.github.io/tocbot/)\n- [Storybook uses Tocbot](https://storybook.js.org/docs/writing-docs/autodocs#configure-the-table-of-contents)\n - Tocbot is used under the hood in storybook to provide TOC generation for component docs in storybook.\n\nIf you'd like to add your page to this list open a pull request.\n\n\n## Requirements\n\nThis library uses **vanilla JavaScript**. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.\n\nThis script works in **all modern browsers and IE 9+**.\n\n**Make sure rendered headings have id attributes**, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this. If you need to do this client side see [this script](https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js).\n\n**NOTE:** to exclude anchor elements from smooth scrolling, add the class `no-smooth-scroll`.\n\n\n### Fixed headers\n\nTo handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a `40px` tall fixed header would be:\n\n```js\ntocbot.init({\n headingsOffset: 40,\n scrollSmoothOffset: -40\n})\n```\n\n\n## API\n\n### Options\n\n```javascript\n// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false\n```\n\n\n### Methods\n\n#### .init\n\nInitialize tocbot with an options object.\n\n```javascript\ntocbot.init(options)\n```\n\n#### .destroy\n\nDestroy tocbot and remove event listeners.\n\n```javascript\ntocbot.destroy()\n```\n\n#### .refresh\n\nRefresh tocbot if the document changes and it needs to be rebuilt.\n\n```javascript\ntocbot.refresh()\n```\n\n\n## Troubleshooting\n\n- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add.\n- If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330).\n\n## Sponsors\n\nIf you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the \"Sponsor\" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!\n\nSponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!\n\n![Roboflow](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/roboflow.png)\n
\nRoboflow\n\n![GetSentry](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/getsentry.png)\n
\nGet Sentry\n\n## Contributing\n\nContributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.\n\nIf you want to open a pull request just fork the repo but please make sure all tests and lint pass.\n\n\n### Running Tests\n\n```bash\nnpm run test\n```\n\n### Steps to publish\n\n- Push a branch and open a pull request\n- run `npm version `\n- Update readme.md with notes\n- Merge the pull request\n- commit dist/\n- run `npm publish`\n- make release on github\n\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)", + "bodyHtml": "

\nTocbot\n

\n

\"github-actions\"\n\"cdnjs\"\n\"GitHub

\n

Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.

\n

Get Started

\n

You can use npm to install it or include the script on the page with HTML.

\n

Download it here

\n

Include JS

\n

Install it with npm.

\n
npm install --save tocbot

Then use with either commonjs or ESM imports:

\n
const tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()

OR

\n

Include the script at the bottom of the page before the closing body tag.

\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.min.js"></script>

Include CSS

\n

CSS is used for expanding & collapsing groupings and some basic styling.

\n
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.css">

OR

\n

If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info

\n
@import 'tocbot/src/scss/tocbot';

Usage

\n

Initialize the script at the bottom of the page before the closing body tag.

\n
tocbot.init({\n  // Where to render the table of contents.\n  tocSelector: '.js-toc',\n  // Where to grab the headings to build the table of contents.\n  contentSelector: '.js-toc-content',\n  // Which headings to grab inside of the contentSelector element.\n  headingSelector: 'h1, h2, h3',\n  // For headings inside relative or absolute positioned containers within content.\n  hasInnerContainers: true,\n});

NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: marked can be configured to generate IDs based on patterns you define; Showdown.js generates IDs by default.

\n

If content in the div has changed then trigger a refresh (optionally with new options).

\n
tocbot.refresh();

Also you can use it within typescript:

\n
import * as tocbot from 'tocbot';\n\ntocbot.init({\n  // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();

Examples

\n\n

If you'd like to add your page to this list open a pull request.

\n

Requirements

\n

This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.

\n

This script works in all modern browsers and IE 9+.

\n

Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.

\n

NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll.

\n

Fixed headers

\n

To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px tall fixed header would be:

\n
tocbot.init({\n  headingsOffset: 40,\n  scrollSmoothOffset: -40\n})

API

\n

Options

\n
// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false

Methods

\n

.init

\n

Initialize tocbot with an options object.

\n
tocbot.init(options)

.destroy

\n

Destroy tocbot and remove event listeners.

\n
tocbot.destroy()

.refresh

\n

Refresh tocbot if the document changes and it needs to be rebuilt.

\n
tocbot.refresh()

Troubleshooting

\n
    \n
  • Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n
      \n
    • Try running this from the console: tocbot.refresh({ ...tocbot.options, hasInnerContainers: true }). If that works then one option (hasInnerContainers: true) to handle inner containers should be all you need to add.
    • \n
    \n
  • \n
  • If you have a really long TOC and are seeing headings getting truncated, then have a look at this issue for a workaround to resolve it.
  • \n
\n

Sponsors

\n

If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting the tocbot repo on github and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!

\n

Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!

\n

\"Roboflow\"\n
\nRoboflow

\n

\"GetSentry\"\n
\nGet Sentry

\n

Contributing

\n

Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.

\n

If you want to open a pull request just fork the repo but please make sure all tests and lint pass.

\n

Running Tests

\n
npm run test

Steps to publish

\n
    \n
  • Push a branch and open a pull request
  • \n
  • run npm version <patch|minor|major>
  • \n
  • Update readme.md with notes
  • \n
  • Merge the pull request
  • \n
  • commit dist/
  • \n
  • run npm publish
  • \n
  • make release on github
  • \n
\n

License

\n

MIT

\n", "title": "Tocbot", "dir": "data", "base": "README.json", From 259455a1552b427c5dc9c600cca6cc1143aefd45 Mon Sep 17 00:00:00 2001 From: Tim Scanlin Date: Wed, 15 Jan 2025 19:54:43 -0800 Subject: [PATCH 4/5] content tweaks --- README.md | 15 ++++++++------- data/README.json | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3d56c848..0bd9d226 100644 --- a/README.md +++ b/README.md @@ -289,17 +289,18 @@ tocbot.refresh() ## Sponsors -If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you! +If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Sponsors that contribute $5 /month or more will have their logos shown below. Thank you! -Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors! +Get Sentry +  +Get Sentry +

-![Roboflow](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/roboflow.png) -
+Roboflow +  Roboflow +

-![GetSentry](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/getsentry.png) -
-Get Sentry ## Contributing diff --git a/data/README.json b/data/README.json index 931bda22..858abe89 100644 --- a/data/README.json +++ b/data/README.json @@ -1,6 +1,6 @@ { - "bodyContent": "

\nTocbot\n

\n\n\"github-actions\"\n\"cdnjs\"\n\"GitHub\n\nTocbot builds a [table of contents](https://en.wikipedia.org/wiki/Table_of_contents) (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by [Tocify](http://gregfranko.com/jquery.tocify.js/), the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.\n\n\n## Get Started\n\nYou can use npm to install it or include the script on the page with HTML.\n\n[**Download it here**](https://github.com/tscanlin/tocbot/releases/)\n\n\n### Include JS\n\nInstall it with npm.\n\n```sh\nnpm install --save tocbot\n```\n\nThen use with either commonjs or ESM imports:\n\n```js\nconst tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()\n```\n\nOR\n\nInclude the script at the bottom of the page before the closing body tag.\n\n```html\n\n```\n\n\n### Include CSS\n\nCSS is used for expanding & collapsing groupings and some basic styling.\n\n```html\n\n```\n\nOR\n\nIf you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', [see the includePath option documentation for more info](https://github.com/sass/node-sass#includepaths)\n\n```scss\n@import 'tocbot/src/scss/tocbot';\n```\n\n\n### Usage\n\nInitialize the script at the bottom of the page before the closing body tag.\n\n```js\ntocbot.init({\n // Where to render the table of contents.\n tocSelector: '.js-toc',\n // Where to grab the headings to build the table of contents.\n contentSelector: '.js-toc-content',\n // Which headings to grab inside of the contentSelector element.\n headingSelector: 'h1, h2, h3',\n // For headings inside relative or absolute positioned containers within content.\n hasInnerContainers: true,\n});\n```\n\n**NOTE:** Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: [marked](https://github.com/markedjs/marked) [can be configured to generate IDs based on patterns you define](https://github.com/markedjs/marked/issues/326#issuecomment-2567091770); [Showdown.js](https://showdownjs.com) generates IDs by default.\n\nIf content in the div has changed then trigger a refresh (optionally with new options).\n\n```javascript\ntocbot.refresh();\n```\n\nAlso you can use it within typescript:\n\n```typescript\nimport * as tocbot from 'tocbot';\n\ntocbot.init({\n // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();\n```\n\n## Examples\n\n- [Tocbot Homepage](https://tscanlin.github.io/tocbot/)\n- [Storybook uses Tocbot](https://storybook.js.org/docs/writing-docs/autodocs#configure-the-table-of-contents)\n - Tocbot is used under the hood in storybook to provide TOC generation for component docs in storybook.\n\nIf you'd like to add your page to this list open a pull request.\n\n\n## Requirements\n\nThis library uses **vanilla JavaScript**. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.\n\nThis script works in **all modern browsers and IE 9+**.\n\n**Make sure rendered headings have id attributes**, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this. If you need to do this client side see [this script](https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js).\n\n**NOTE:** to exclude anchor elements from smooth scrolling, add the class `no-smooth-scroll`.\n\n\n### Fixed headers\n\nTo handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a `40px` tall fixed header would be:\n\n```js\ntocbot.init({\n headingsOffset: 40,\n scrollSmoothOffset: -40\n})\n```\n\n\n## API\n\n### Options\n\n```javascript\n// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false\n```\n\n\n### Methods\n\n#### .init\n\nInitialize tocbot with an options object.\n\n```javascript\ntocbot.init(options)\n```\n\n#### .destroy\n\nDestroy tocbot and remove event listeners.\n\n```javascript\ntocbot.destroy()\n```\n\n#### .refresh\n\nRefresh tocbot if the document changes and it needs to be rebuilt.\n\n```javascript\ntocbot.refresh()\n```\n\n\n## Troubleshooting\n\n- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add.\n- If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330).\n\n## Sponsors\n\nIf you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the \"Sponsor\" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!\n\nSponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!\n\n![Roboflow](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/roboflow.png)\n
\nRoboflow\n\n![GetSentry](https://raw.githubusercontent.com/tscanlin/tocbot/add-sponsors-section/static/img/getsentry.png)\n
\nGet Sentry\n\n## Contributing\n\nContributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.\n\nIf you want to open a pull request just fork the repo but please make sure all tests and lint pass.\n\n\n### Running Tests\n\n```bash\nnpm run test\n```\n\n### Steps to publish\n\n- Push a branch and open a pull request\n- run `npm version `\n- Update readme.md with notes\n- Merge the pull request\n- commit dist/\n- run `npm publish`\n- make release on github\n\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)", - "bodyHtml": "

\nTocbot\n

\n

\"github-actions\"\n\"cdnjs\"\n\"GitHub

\n

Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.

\n

Get Started

\n

You can use npm to install it or include the script on the page with HTML.

\n

Download it here

\n

Include JS

\n

Install it with npm.

\n
npm install --save tocbot

Then use with either commonjs or ESM imports:

\n
const tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()

OR

\n

Include the script at the bottom of the page before the closing body tag.

\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.min.js"></script>

Include CSS

\n

CSS is used for expanding & collapsing groupings and some basic styling.

\n
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.css">

OR

\n

If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info

\n
@import 'tocbot/src/scss/tocbot';

Usage

\n

Initialize the script at the bottom of the page before the closing body tag.

\n
tocbot.init({\n  // Where to render the table of contents.\n  tocSelector: '.js-toc',\n  // Where to grab the headings to build the table of contents.\n  contentSelector: '.js-toc-content',\n  // Which headings to grab inside of the contentSelector element.\n  headingSelector: 'h1, h2, h3',\n  // For headings inside relative or absolute positioned containers within content.\n  hasInnerContainers: true,\n});

NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: marked can be configured to generate IDs based on patterns you define; Showdown.js generates IDs by default.

\n

If content in the div has changed then trigger a refresh (optionally with new options).

\n
tocbot.refresh();

Also you can use it within typescript:

\n
import * as tocbot from 'tocbot';\n\ntocbot.init({\n  // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();

Examples

\n\n

If you'd like to add your page to this list open a pull request.

\n

Requirements

\n

This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.

\n

This script works in all modern browsers and IE 9+.

\n

Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.

\n

NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll.

\n

Fixed headers

\n

To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px tall fixed header would be:

\n
tocbot.init({\n  headingsOffset: 40,\n  scrollSmoothOffset: -40\n})

API

\n

Options

\n
// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false

Methods

\n

.init

\n

Initialize tocbot with an options object.

\n
tocbot.init(options)

.destroy

\n

Destroy tocbot and remove event listeners.

\n
tocbot.destroy()

.refresh

\n

Refresh tocbot if the document changes and it needs to be rebuilt.

\n
tocbot.refresh()

Troubleshooting

\n
    \n
  • Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n
      \n
    • Try running this from the console: tocbot.refresh({ ...tocbot.options, hasInnerContainers: true }). If that works then one option (hasInnerContainers: true) to handle inner containers should be all you need to add.
    • \n
    \n
  • \n
  • If you have a really long TOC and are seeing headings getting truncated, then have a look at this issue for a workaround to resolve it.
  • \n
\n

Sponsors

\n

If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting the tocbot repo on github and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Thank you!

\n

Sponsors that contribute $5 /month or more will have their logos shown below. Thank you to the existing sponsors!

\n

\"Roboflow\"\n
\nRoboflow

\n

\"GetSentry\"\n
\nGet Sentry

\n

Contributing

\n

Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.

\n

If you want to open a pull request just fork the repo but please make sure all tests and lint pass.

\n

Running Tests

\n
npm run test

Steps to publish

\n
    \n
  • Push a branch and open a pull request
  • \n
  • run npm version <patch|minor|major>
  • \n
  • Update readme.md with notes
  • \n
  • Merge the pull request
  • \n
  • commit dist/
  • \n
  • run npm publish
  • \n
  • make release on github
  • \n
\n

License

\n

MIT

\n", + "bodyContent": "

\nTocbot\n

\n\n\"github-actions\"\n\"cdnjs\"\n\"GitHub\n\nTocbot builds a [table of contents](https://en.wikipedia.org/wiki/Table_of_contents) (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by [Tocify](http://gregfranko.com/jquery.tocify.js/), the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.\n\n\n## Get Started\n\nYou can use npm to install it or include the script on the page with HTML.\n\n[**Download it here**](https://github.com/tscanlin/tocbot/releases/)\n\n\n### Include JS\n\nInstall it with npm.\n\n```sh\nnpm install --save tocbot\n```\n\nThen use with either commonjs or ESM imports:\n\n```js\nconst tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()\n```\n\nOR\n\nInclude the script at the bottom of the page before the closing body tag.\n\n```html\n\n```\n\n\n### Include CSS\n\nCSS is used for expanding & collapsing groupings and some basic styling.\n\n```html\n\n```\n\nOR\n\nIf you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', [see the includePath option documentation for more info](https://github.com/sass/node-sass#includepaths)\n\n```scss\n@import 'tocbot/src/scss/tocbot';\n```\n\n\n### Usage\n\nInitialize the script at the bottom of the page before the closing body tag.\n\n```js\ntocbot.init({\n // Where to render the table of contents.\n tocSelector: '.js-toc',\n // Where to grab the headings to build the table of contents.\n contentSelector: '.js-toc-content',\n // Which headings to grab inside of the contentSelector element.\n headingSelector: 'h1, h2, h3',\n // For headings inside relative or absolute positioned containers within content.\n hasInnerContainers: true,\n});\n```\n\n**NOTE:** Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: [marked](https://github.com/markedjs/marked) [can be configured to generate IDs based on patterns you define](https://github.com/markedjs/marked/issues/326#issuecomment-2567091770); [Showdown.js](https://showdownjs.com) generates IDs by default.\n\nIf content in the div has changed then trigger a refresh (optionally with new options).\n\n```javascript\ntocbot.refresh();\n```\n\nAlso you can use it within typescript:\n\n```typescript\nimport * as tocbot from 'tocbot';\n\ntocbot.init({\n // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();\n```\n\n## Examples\n\n- [Tocbot Homepage](https://tscanlin.github.io/tocbot/)\n- [Storybook uses Tocbot](https://storybook.js.org/docs/writing-docs/autodocs#configure-the-table-of-contents)\n - Tocbot is used under the hood in storybook to provide TOC generation for component docs in storybook.\n\nIf you'd like to add your page to this list open a pull request.\n\n\n## Requirements\n\nThis library uses **vanilla JavaScript**. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.\n\nThis script works in **all modern browsers and IE 9+**.\n\n**Make sure rendered headings have id attributes**, some markdown libraries (like [marked](https://github.com/chjj/marked)) already do this. If you need to do this client side see [this script](https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js).\n\n**NOTE:** to exclude anchor elements from smooth scrolling, add the class `no-smooth-scroll`.\n\n\n### Fixed headers\n\nTo handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a `40px` tall fixed header would be:\n\n```js\ntocbot.init({\n headingsOffset: 40,\n scrollSmoothOffset: -40\n})\n```\n\n\n## API\n\n### Options\n\n```javascript\n// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false\n```\n\n\n### Methods\n\n#### .init\n\nInitialize tocbot with an options object.\n\n```javascript\ntocbot.init(options)\n```\n\n#### .destroy\n\nDestroy tocbot and remove event listeners.\n\n```javascript\ntocbot.destroy()\n```\n\n#### .refresh\n\nRefresh tocbot if the document changes and it needs to be rebuilt.\n\n```javascript\ntocbot.refresh()\n```\n\n\n## Troubleshooting\n\n- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n - Try running this from the console: `tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })`. If that works then one option (`hasInnerContainers: true`) to handle inner containers should be all you need to add.\n- If you have a really long TOC and are seeing headings getting truncated, then have a [look at this issue for a workaround to resolve it](https://github.com/tscanlin/tocbot/issues/330).\n\n## Sponsors\n\nIf you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting [the tocbot repo on github](https://github.com/tscanlin/tocbot) and clicking the \"Sponsor\" button at the top of the page. This will help me continue to develop and maintain Tocbot. Sponsors that contribute $5 /month or more will have their logos shown below. Thank you!\n\n\"Get\n \nGet Sentry\n

\n\n\"Roboflow\"\n \nRoboflow\n

\n\n\n## Contributing\n\nContributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.\n\nIf you want to open a pull request just fork the repo but please make sure all tests and lint pass.\n\n\n### Running Tests\n\n```bash\nnpm run test\n```\n\n### Steps to publish\n\n- Push a branch and open a pull request\n- run `npm version `\n- Update readme.md with notes\n- Merge the pull request\n- commit dist/\n- run `npm publish`\n- make release on github\n\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)", + "bodyHtml": "

\nTocbot\n

\n

\"github-actions\"\n\"cdnjs\"\n\"GitHub

\n

Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.

\n

Get Started

\n

You can use npm to install it or include the script on the page with HTML.

\n

Download it here

\n

Include JS

\n

Install it with npm.

\n
npm install --save tocbot

Then use with either commonjs or ESM imports:

\n
const tocbot = require('tocbot/dist/tocbot.js')\n// OR\nimport tocbot from 'tocbot'\n\n// Initialize tocbot\ntocbot.init()

OR

\n

Include the script at the bottom of the page before the closing body tag.

\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.min.js"></script>

Include CSS

\n

CSS is used for expanding & collapsing groupings and some basic styling.

\n
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.30.0/tocbot.css">

OR

\n

If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info

\n
@import 'tocbot/src/scss/tocbot';

Usage

\n

Initialize the script at the bottom of the page before the closing body tag.

\n
tocbot.init({\n  // Where to render the table of contents.\n  tocSelector: '.js-toc',\n  // Where to grab the headings to build the table of contents.\n  contentSelector: '.js-toc-content',\n  // Which headings to grab inside of the contentSelector element.\n  headingSelector: 'h1, h2, h3',\n  // For headings inside relative or absolute positioned containers within content.\n  hasInnerContainers: true,\n});

NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading. Some markdown libraries already do this for you: marked can be configured to generate IDs based on patterns you define; Showdown.js generates IDs by default.

\n

If content in the div has changed then trigger a refresh (optionally with new options).

\n
tocbot.refresh();

Also you can use it within typescript:

\n
import * as tocbot from 'tocbot';\n\ntocbot.init({\n  // Options\n});\n\ntocbot.refresh();\n\ntocbot.destroy();

Examples

\n\n

If you'd like to add your page to this list open a pull request.

\n

Requirements

\n

This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.

\n

This script works in all modern browsers and IE 9+.

\n

Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.

\n

NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll.

\n

Fixed headers

\n

To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px tall fixed header would be:

\n
tocbot.init({\n  headingsOffset: 40,\n  scrollSmoothOffset: -40\n})

API

\n

Options

\n
// Where to render the table of contents.\ntocSelector: '.js-toc',\n// Or, you can pass in a DOM node instead\ntocElement: null,\n// Where to grab the headings to build the table of contents.\ncontentSelector: '.js-toc-content',\n// Or, you can pass in a DOM node instead\ncontentElement: null,\n// Which headings to grab inside of the contentSelector element.\nheadingSelector: 'h1, h2, h3',\n// Headings that match the ignoreSelector will be skipped.\nignoreSelector: '.js-toc-ignore',\n// For headings inside relative or absolute positioned\n// containers within content.\nhasInnerContainers: false,\n// Main class to add to links.\nlinkClass: 'toc-link',\n// Extra classes to add to links.\nextraLinkClasses: '',\n// Class to add to active links,\n// the link corresponding to the top most heading on the page.\nactiveLinkClass: 'is-active-link',\n// Main class to add to lists.\nlistClass: 'toc-list',\n// Extra classes to add to lists.\nextraListClasses: '',\n// Class that gets added when a list should be collapsed.\nisCollapsedClass: 'is-collapsed',\n// Class that gets added when a list should be able\n// to be collapsed but isn't necessarily collapsed.\ncollapsibleClass: 'is-collapsible',\n// Class to add to list items.\nlistItemClass: 'toc-list-item',\n// Class to add to active list items.\nactiveListItemClass: 'is-active-li',\n// How many heading levels should not be collapsed.\n// For example, number 6 will show everything since\n// there are only 6 heading levels and number 0 will collapse them all.\n// The sections that are hidden will open\n// and close as you scroll to headings within them.\ncollapseDepth: 0,\n// Smooth scrolling enabled.\nscrollSmooth: true,\n// Smooth scroll duration.\nscrollSmoothDuration: 420,\n// Smooth scroll offset.\nscrollSmoothOffset: 0,\n// Callback for scroll end.\nscrollEndCallback: function (e) {},\n// Headings offset between the headings and the top of\n// the document (this is meant for minor adjustments).\nheadingsOffset: 1,\n// Timeout between events firing to make sure it's\n// not too rapid (for performance reasons).\nthrottleTimeout: 50,\n// Element to add the positionFixedClass to.\npositionFixedSelector: null,\n// Fixed position class to add to make sidebar fixed after scrolling\n// down past the fixedSidebarOffset.\npositionFixedClass: 'is-position-fixed',\n// fixedSidebarOffset can be any number but by default is set\n// to auto which sets the fixedSidebarOffset to the sidebar\n// element's offsetTop from the top of the document on init.\nfixedSidebarOffset: 'auto',\n// includeHtml can be set to true to include the HTML markup from the\n// heading node instead of just including the innerText.\nincludeHtml: false,\n// includeTitleTags automatically sets the html title tag of the link\n// to match the title. This can be useful for SEO purposes or\n// when truncating titles.\nincludeTitleTags: false,\n// onclick function to apply to all links in toc. will be called with\n// the event as the first parameter, and this can be used to stop,\n// propagation, prevent default or perform action\nonClick: function (e) {},\n// orderedList can be set to false to generate unordered lists (ul)\n// instead of ordered lists (ol)\norderedList: true,\n// If there is a fixed article scroll container, set to calculate offset.\nscrollContainer: null,\n// prevent ToC DOM rendering if it's already rendered by an external system.\nskipRendering: false,\n// Optional callback to change heading labels.\n// For example it can be used to cut down and put ellipses on multiline headings you deem too long.\n// Called each time a heading is parsed. Expects a string and returns the modified label to display.\n// Additionally, the attribute `data-heading-label` may be used on a heading to specify\n// a shorter string to be used in the TOC.\n// function (string) => string\nheadingLabelCallback: false,\n// ignore headings that are hidden in DOM\nignoreHiddenElements: false,\n// Optional callback to modify properties of parsed headings.\n// The heading element is passed in node parameter and information\n// parsed by default parser is provided in obj parameter.\n// Function has to return the same or modified obj.\n// The heading will be excluded from TOC if nothing is returned.\n// function (object, HTMLElement) => object | void\nheadingObjectCallback: null,\n// Set the base path, useful if you use a `base` tag in `head`.\nbasePath: '',\n// Only takes affect when `tocSelector` is scrolling,\n// keep the toc scroll position in sync with the content.\ndisableTocScrollSync: false,\n// If this is null then just use `tocElement` or `tocSelector` instead\n// assuming `disableTocScrollSync` is set to false. This allows for\n// scrolling an outer element (like a nav panel w/ search) containing the toc.\n// Please pass an element, not a selector here.\ntocScrollingWrapper: null,\n// Offset for the toc scroll (top) position when scrolling the page.\n// Only effective if `disableTocScrollSync` is false.\ntocScrollOffset: 30,\n// Enable the URL hash to update with the proper heading ID as\n// a user scrolls the page.\nenableUrlHashUpdateOnScroll: false

Methods

\n

.init

\n

Initialize tocbot with an options object.

\n
tocbot.init(options)

.destroy

\n

Destroy tocbot and remove event listeners.

\n
tocbot.destroy()

.refresh

\n

Refresh tocbot if the document changes and it needs to be rebuilt.

\n
tocbot.refresh()

Troubleshooting

\n
    \n
  • Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section\n
      \n
    • Try running this from the console: tocbot.refresh({ ...tocbot.options, hasInnerContainers: true }). If that works then one option (hasInnerContainers: true) to handle inner containers should be all you need to add.
    • \n
    \n
  • \n
  • If you have a really long TOC and are seeing headings getting truncated, then have a look at this issue for a workaround to resolve it.
  • \n
\n

Sponsors

\n

If you find Tocbot useful, consider supporting it by becoming a sponsor. You can do this by visiting the tocbot repo on github and clicking the "Sponsor" button at the top of the page. This will help me continue to develop and maintain Tocbot. Sponsors that contribute $5 /month or more will have their logos shown below. Thank you!

\n\"Get\n \nGet Sentry\n

\n\"Roboflow\"\n \nRoboflow\n

\n

Contributing

\n

Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.

\n

If you want to open a pull request just fork the repo but please make sure all tests and lint pass.

\n

Running Tests

\n
npm run test

Steps to publish

\n
    \n
  • Push a branch and open a pull request
  • \n
  • run npm version <patch|minor|major>
  • \n
  • Update readme.md with notes
  • \n
  • Merge the pull request
  • \n
  • commit dist/
  • \n
  • run npm publish
  • \n
  • make release on github
  • \n
\n

License

\n

MIT

\n", "title": "Tocbot", "dir": "data", "base": "README.json", From 3838b76af350dd170cdd3714392619fdff3301f8 Mon Sep 17 00:00:00 2001 From: Tim Scanlin Date: Wed, 15 Jan 2025 20:07:58 -0800 Subject: [PATCH 5/5] also add script to help keep the readme version more up to date --- scripts/update-readme-versions.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 scripts/update-readme-versions.js diff --git a/scripts/update-readme-versions.js b/scripts/update-readme-versions.js new file mode 100755 index 00000000..e9e1ae30 --- /dev/null +++ b/scripts/update-readme-versions.js @@ -0,0 +1,20 @@ +import * as fs from 'fs'; +import pkg from '../package.json' with { type: 'json' }; + +const readmePath = 'README.md'; +const thisScriptPath = 'scripts/update-readme-versions.js'; + +const LAST_VERSION = '4.30.0' +const NEW_VERSION = pkg.version + +function replaceOldVersionWithNew() { + // For readme. + const updatedReadmeContent = fs.readFileSync(readmePath, 'utf8').replaceAll(LAST_VERSION, NEW_VERSION); + fs.writeFileSync(readmePath, updatedReadmeContent, 'utf8'); + + // For this script. + const updatedScriptContent = fs.readFileSync(thisScriptPath, 'utf8').replaceAll(LAST_VERSION, NEW_VERSION); + fs.writeFileSync(thisScriptPath, updatedScriptContent, 'utf8'); +} + +replaceOldVersionWithNew()