generated from JS-DevTools/template-node-typescript
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathoptions.ts
145 lines (128 loc) · 4.47 KB
/
options.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { Node } from "unist";
import { CustomizationHook } from "./customization-hooks";
import { HeadingTagName, HtmlElementNode, ListItemNode } from "./types";
/**
* The different positions at which the table of contents can be inserted,
* relative to the `<main>` element.
*/
export type InsertPosition = "beforebegin" | "afterbegin" | "beforeend" | "afterend";
/**
* Options for the Rehype TOC plugin
*/
export interface Options {
/**
* Determines whether the table of contents is wrapped in a `<nav>` element.
*
* Defaults to `true`.
*/
nav?: boolean;
/**
* The position at which the table of contents should be inserted, relative to the `<main>`
* element.
*
* Defaults to "afterbegin";
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement
*/
position?: InsertPosition;
/**
* HTML heading elements to include in the table of contents.
*
* Defaults to all headings ("h1" through "h6").
*/
headings?: HeadingTagName[];
/**
* CSS class names for various parts of the table of contents.
*/
cssClasses?: CssClasses;
/**
* Allows you to customize the table of contents before it is added to the page.
*
* @param toc - The table of contents HAST node tree
* @returns - Return the modified node, a new node to replace it with, or `undefined` to use the
* existing node. You can return a falsy value to prevent the table of contents from being added
* to the page.
*/
customizeTOC?(toc: HtmlElementNode): Node | boolean | undefined;
/**
* Allows you to customize an item before it is added to the table of contents.
*
* @param tocItem - A HAST node tree containing an `<li>` and `<a>`
* @param heading - The original heading (e.g. `<h1>`, `<h2>`, etc.) that `tocItem` is a referene to
*
* @returns - Return the modified node, a new node to replace it with, or `undefined` to use the
* existing node. You can return a falsy value to prevent the item from being added to the
* table of contents.
*/
customizeTOCItem?(tocItem: ListItemNode, heading: HtmlElementNode): Node | boolean | undefined;
}
/**
* CSS class names for various parts of the table of contents.
*/
export interface CssClasses {
/**
* The CSS class name for the top-level `<nav>` or `<ol>` element that contains the whole table of contents.
*
* Defaults to "toc".
*/
toc?: string;
/**
* The CSS class name for all `<ol>` elements in the table of contents, including the top-level one.
*
* Defaults to "toc-level", which also adds "toc-level-1", "toc-level-2", etc.
*/
list?: string;
/**
* The CSS class name for all `<li>` elements in the table of contents.
*
* Defaults to "toc-item", which also adds "toc-item-h1", "toc-item-h2", etc.
*/
listItem?: string;
/**
* The CSS class name for all `<a>` elements in the table of contents.
*
* Defaults to "toc-link", which also adds "toc-link-h1", "toc-link-h2", etc.
*/
link?: string;
}
/**
* Normalized, sanitized, and complete settings,
* with default values for anything that wasn't specified by the caller.
*/
export class NormalizedOptions {
public readonly nav: boolean;
public readonly position: InsertPosition;
public readonly headings: HeadingTagName[];
public readonly cssClasses: Required<CssClasses>;
public readonly customizeTOC?: CustomizationHook;
public readonly customizeTOCItem?: CustomizationHook;
/**
* Applies default values for any unspecified options
*/
public constructor(options: Options = {}) {
let cssClasses = options.cssClasses || {};
this.nav = options.nav === undefined ? true : Boolean(options.nav);
this.position = options.position || "afterbegin";
this.headings = options.headings || ["h1", "h2", "h3", "h4", "h5", "h6"];
this.cssClasses = {
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,
};
this.customizeTOC = options.customizeTOC;
this.customizeTOCItem = options.customizeTOCItem;
}
}
/**
* Builds a CSS class string from the given user-defined class name
*/
export function buildClass(name: string, suffix: string | number): string | undefined {
if (name) {
let cssClass = name;
if (suffix) {
cssClass += ` ${name}-${suffix}`;
}
return cssClass;
}
}