New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

rehype-toc

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rehype-toc - npm Package Compare versions

Comparing version

to
1.0.0

47

lib/create-toc.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const get_inner_text_1 = require("./get-inner-text");
const options_1 = require("./options");
/**

@@ -8,10 +9,10 @@ * Creates an `<ol>` element containing the table of contents.

function createTOC(headings, options) {
let levels = [];
let currentLevel = {
depth: 0,
headingNumber: 0,
list: createList(undefined, 1, options),
list: undefined,
};
let levels = [currentLevel];
for (let heading of headings) {
let headingNumber = options.headings.indexOf(heading.tagName) + 1;
let headingNumber = parseInt(heading.tagName.slice(-1), 10);
if (headingNumber > currentLevel.headingNumber) {

@@ -26,4 +27,6 @@ // This is a higher heading number, so start a new level

// Add the new list to the previous level's list
let lastItem = currentLevel.list.children.slice(-1)[0];
lastItem && lastItem.children.push(level.list);
if (currentLevel.list) {
let lastItem = currentLevel.list.children.slice(-1)[0];
lastItem.children.push(level.list);
}
levels.push(level);

@@ -34,10 +37,14 @@ currentLevel = level;

if (headingNumber < currentLevel.headingNumber) {
// This is a lower heading number, so we need to go up to the corresponding previous level
do {
levels.pop();
currentLevel = levels.slice(-1)[0];
if (currentLevel.headingNumber === headingNumber) {
// This is a lower heading number, so we need to go up to a previous level
for (let i = levels.length - 2; i >= 0; i--) {
let level = levels[i];
if (level.headingNumber === headingNumber) {
// We found the previous level that matches this heading
levels = levels.slice(0, i + 1);
currentLevel = level;
break;
}
} while (levels.length > 1);
}
// If headings are in an incorrect order, then we may need to adjust the headingNumber
currentLevel.headingNumber = Math.min(currentLevel.headingNumber, headingNumber);
}

@@ -50,4 +57,8 @@ // This heading is the same level as the previous heading,

}
let toc = levels.pop().list;
return toc;
if (levels.length === 0) {
return createList(undefined, 1, options);
}
else {
return levels[0].list;
}
}

@@ -63,3 +74,3 @@ exports.createTOC = createTOC;

properties: {
class: `${options.cssClasses.list} ${options.cssClasses.list}-${depth}`,
class: options_1.buildClass(options.cssClasses.list, depth),
},

@@ -72,5 +83,5 @@ children: [],

}
if (depth === 1) {
if (depth === 1 && options.cssClasses.toc) {
// This is the top-level table of contents list
list.properties.class = options.cssClasses.toc + " " + list.properties.class;
list.properties.class = options.cssClasses.toc + " " + (list.properties.class || "");
}

@@ -87,3 +98,3 @@ return list;

properties: {
class: `${options.cssClasses.listItem} ${options.cssClasses.listItem}-${heading.tagName}`,
class: options_1.buildClass(options.cssClasses.listItem, heading.tagName),
},

@@ -95,4 +106,4 @@ children: [

properties: {
class: options_1.buildClass(options.cssClasses.link, heading.tagName),
href: `#${heading.properties.id || ""}`,
class: `${options.cssClasses.link} ${options.cssClasses.link}-${heading.tagName}`,
},

@@ -99,0 +110,0 @@ children: [

import { toc } from "./rehype-toc";
export { Options } from "./options";
export { Options, PartialOptions } from "./options";
export * from "./types";
export { toc };
export default toc;

@@ -66,1 +66,5 @@ import { Node } from "unist";

export declare function applyDefaults(config?: PartialOptions): Options;
/**
* Builds a CSS class string from the given user-defined class name
*/
export declare function buildClass(name: string, suffix: string | number): string | undefined;

@@ -11,6 +11,6 @@ "use strict";

cssClasses: {
toc: cssClasses.toc || "toc",
list: cssClasses.list || "toc-level",
listItem: cssClasses.listItem || "toc-item",
link: cssClasses.link || "toc-link",
toc: cssClasses.toc === undefined ? "toc" : cssClasses.toc,
list: cssClasses.list === undefined ? "toc-level" : cssClasses.list,
listItem: cssClasses.listItem === undefined ? "toc-item" : cssClasses.listItem,
link: cssClasses.link === undefined ? "toc-link" : cssClasses.link,
},

@@ -21,2 +21,15 @@ customizeTOC: config.customizeTOC || ((toc) => toc),

exports.applyDefaults = applyDefaults;
/**
* Builds a CSS class string from the given user-defined class name
*/
function buildClass(name, suffix) {
if (name) {
let cssClass = name;
if (suffix) {
cssClass += ` ${name}-${suffix}`;
}
return cssClass;
}
}
exports.buildClass = buildClass;
//# sourceMappingURL=options.js.map

@@ -36,5 +36,2 @@ import { Node } from "unist";

tagName: "ol" | "ul";
properties: {
class: string;
};
children: ListItemNode[];

@@ -48,6 +45,3 @@ }

tagName: "li";
properties: {
class: string;
};
children: Array<HtmlElementNode | TextNode>;
children: Node[];
}
{
"name": "rehype-toc",
"version": "1.0.0-alpha.1",
"version": "1.0.0",
"description": "A rehype plugin that adds a table of contents (TOC) to the page",

@@ -59,2 +59,3 @@ "keywords": [

"rehype-parse": "^6.0.0",
"rehype-slug": "^2.0.3",
"rehype-stringify": "^6.0.0",

@@ -61,0 +62,0 @@ "shx": "^0.3.2",

# Table of Contents plugin for rehype
A rehype plugin that adds a table of contents (TOC) to the page
A [rehype](https://github.com/rehypejs/rehype) plugin that adds a table of contents (TOC) to the page

@@ -15,13 +15,165 @@ [![Cross-Platform Compatibility](https://jsdevtools.org/img/badges/os-badges.svg)](https://travis-ci.com/JS-DevTools/rehype-toc)

Features
--------------------------
- Adds an `<ol>` list outlining all headings on the page
- Combine with [rehype-slug](https://github.com/rehypejs/rehype-slug) to create links to each heading
- Ignores headings outside of `<main>` if it exists
- You can customize which headings are included (defaults to `<h1>` - `<h6>`)
- You can customize the CSS classes on every TOC element
- Hooks give you complete customization of the generated HTML
Example
--------------------------
**input.html**<br>
Here's the original HTML file. There are three levels of headings (`<h1>` - `<h3>`), and none of them have IDs.
```html
<html>
<body>
<h1>Apple Pie Recipe</h1>
<p>This is the world's best apple pie recipe...</p>
<div>
<h2>Filling</h2>
<p>The filling is the best part...</p>
<h3>Preparing the apples</h3>
<p>Cut the apples into 1/4 inch slices...</p>
<h3>Preparing the spice mix</h3>
<p>In a mixing bowl, combine sugar, cinnamon...</p>
</div>
<div>
<h2>Crust</h2>
<p>How to make the perfect flaky crust...</p>
<h3>Preparing the dough</h3>
<p>Combine flour, sugar, salt...</p>
<h3>The criss-cross top</h3>
<p>Cut the top crust into 1/2 inch strips...</p>
</div>
</body>
</html>
```
**example.js**<br>
This script reads the `input.html` file above writes the results to `output.html` (shown below). The script uses [unified](https://unified.js.org/), [rehype-parse](https://github.com/rehypejs/rehype/tree/master/packages/rehype-parse), [rehype-slug](https://github.com/rehypejs/rehype-slug), and [rehype-stringify](https://github.com/rehypejs/rehype/tree/master/packages/rehype-stringify).
```javascript
import toc from "rehype-toc";
const unified = require("unified");
const parse = require("rehype-parse");
const slug = require("rehype-slug");
const toc = require("rehype-toc");
const stringify = require("rehype-stringify");
const fs = require("fs");
// TODO: Add a usage example here
async function example() {
// Create a Rehype processor with the TOC plugin
const processor = unified()
.use(parse)
.use(slug)
.use(toc)
.use(stringify);
// Read the original HTML file
let inputHTML = await fs.promises.readFile("input.html");
// Process the HTML, adding heading IDs and Table of Contents
let outputHTML = await processor.process(inputHTML);
// Save the new HTML
await fs.promises.writeFile("output.html", outputHTML);
}
```
**output.html**<br>
Here's the HTML that gets created by the above script. Notice that a table of contents has been added at the top of the `<body>`, with links to each of the headings on the page. The headings also now have IDs, thanks to [rehype-slug](https://github.com/rehypejs/rehype-slug).
```html
<html>
<body>
<ol class="toc toc-level toc-level-1">
<li class="toc-item toc-item-h1">
<a class="toc-link toc-link-h1" href="#apple-pie-recipe">
Apple Pie Recipe
</a>
<ol class="toc-level toc-level-2">
<li class="toc-item toc-item-h2">
<a class="toc-link toc-link-h2" href="#filling">
Filling
</a>
<ol class="toc-level toc-level-3">
<li class="toc-item toc-item-h3">
<a class="toc-link toc-link-h3" href="#preparing-the-apples">
Preparing the apples
</a>
</li>
<li class="toc-item toc-item-h3">
<a class="toc-link toc-link-h3" href="#preparing-the-spice-mix">
Preparing the spice mix
</a>
</li>
</ol>
</li>
<li class="toc-item toc-item-h2">
<a class="toc-link toc-link-h2" href="#crust">
Crust
</a>
<ol class="toc-level toc-level-3">
<li class="toc-item toc-item-h3">
<a class="toc-link toc-link-h3" href="#preparing-the-dough">
Preparing the dough
</a>
</li>
<li class="toc-item toc-item-h3">
<a class="toc-link toc-link-h3" href="#the-criss-cross-top">
The criss-cross top
</a>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<h1 id="apple-pie-recipe">Apple Pie Recipe</h1>
<p>This is the world's best apple pie recipe...</p>
<div>
<h2 id="filling">Filling</h2>
<p>The filling is the best part...</p>
<h3 id="preparing-the-apples">Preparing the apples</h3>
<p>Cut the apples into 1/4 inch slices...</p>
<h3 id="preparing-the-spice-mix">Preparing the spice mix</h3>
<p>In a mixing bowl, combine sugar, cinnamon...</p>
</div>
<div>
<h2 id="crust">Crust</h2>
<p>How to make the perfect flaky crust...</p>
<h3 id="preparing-the-dough">Preparing the dough</h3>
<p>Combine flour, sugar, salt...</p>
<h3 id="the-criss-cross-top">The criss-cross top</h3>
<p>Cut the top crust into 1/2 inch strips...</p>
</div>
</body>
</html>
```
Installation

@@ -35,10 +187,50 @@ --------------------------

You'll probably want to install [unified](https://unified.js.org/), [rehype-parse](https://github.com/rehypejs/rehype/tree/master/packages/rehype-parse), [rehype-stringify](https://github.com/rehypejs/rehype/tree/master/packages/rehype-stringify), and [rehype-slug](https://github.com/rehypejs/rehype-slug) as well.
```bash
npm install unified rehype-parse rehype-stringify rehype-slug
```
Usage
--------------------------
TODO: Document the library's API and CLI usage
Using the Rehype TOC plugin requires an understanding of how to use Unified and Rehype. [Here is an excelleng guide](https://unified.js.org/using-unified.html) to learn the basics.
The Rehype TOC plugin works just like any other Rehype plugin. Pass it to [the `.use()` method](https://github.com/unifiedjs/unified#processoruseplugin-options), optionally with an [options object](#options).
```javascript
const unified = require("unified");
const toc = require("rehype-toc");
// Use the Rehype TOC plugin with its default options
unified().use(toc);
// Use the Rehype TOC plugin with custom options
unified().use(toc, {
headings: ["h1", "h2"], // Only include <h1> and <h2> headings in the TOC
cssClasses: {
toc: "page-outline", // Change the CSS class for the TOC
link: "page-link", // Change the CSS class for links in the TOC
}
});
```
Options
--------------------------
Rehype Rehype TOC supports the following options:
|Option |Type |Default |Description
|:---------------------|:-------------------|:----------------------|:-----------------------------------------
|`headings` |array of strings |h1, h2, h3, h4, h5, h6 |The HTML heading tags to include in the table of contents
|`cssClasses.toc` |string |toc |The CSS class name for the top-level `<ol>` element that contains the whole table of contents.
|`cssClasses.list` |string |toc-level |The CSS class name for all `<ol>` elements in the table of contents, including the top-level one.
|`cssClasses.listItem` |string |toc-item |The CSS class name for all `<li>` elements in the table of contents.
|`cssClasses.link` |string |toc-link |The CSS class name for all `<a>` elements in the table of contents.
|`customizeTOC` |function |no-op |Allows you to customize the table of contents before it is added to the page.<br><br>The function receives the TOC node tree and can modify it in any way you want. Or you can return a new node tree to use instead. Or return `false` to prevent the the TOC from being added to the page.
Contributing

@@ -45,0 +237,0 @@ --------------------------

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet