@substrate-system/markdown-toc 1.3.8 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -19
- package/dist/dom.js +80 -0
- package/dist/dom.js.map +7 -0
- package/dist/index.js +3 -2
- package/dist/index.js.map +2 -2
- package/dist/meta.json +87 -4
- package/dist/preact.js +93 -0
- package/dist/preact.js.map +7 -0
- package/dist/src/dom.d.ts +23 -0
- package/dist/src/dom.d.ts.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/preact.d.ts +12 -0
- package/dist/src/preact.d.ts.map +1 -0
- package/package.json +20 -3
package/README.md
CHANGED
|
@@ -11,6 +11,10 @@ This is a fork of [jonschlinkert/markdown-toc](https://github.com/jonschlinkert/
|
|
|
11
11
|
<details>
|
|
12
12
|
<summary><h2>Contents</h2></summary>
|
|
13
13
|
|
|
14
|
+
- [Install](#install)
|
|
15
|
+
- [Quickstart](#quick-start)
|
|
16
|
+
- [CLI](#cli)
|
|
17
|
+
- [SPA](#spa)
|
|
14
18
|
- [Highlights](#highlights)
|
|
15
19
|
- [Usage](#usage)
|
|
16
20
|
- [API](#api)
|
|
@@ -32,24 +36,12 @@ This is a fork of [jonschlinkert/markdown-toc](https://github.com/jonschlinkert/
|
|
|
32
36
|
|
|
33
37
|
## Install
|
|
34
38
|
|
|
35
|
-
Install with [npm](https://www.npmjs.com/)
|
|
39
|
+
Install with [npm](https://www.npmjs.com/).
|
|
36
40
|
|
|
37
41
|
```sh
|
|
38
|
-
npm i @substrate-system/markdown-toc
|
|
42
|
+
npm i -D @substrate-system/markdown-toc
|
|
39
43
|
```
|
|
40
44
|
|
|
41
|
-
# Sponsors
|
|
42
|
-
|
|
43
|
-
Thanks to the following companies, organizations, and individuals for supporting the ongoing maintenance and development of markdown-toc! [Become a Sponsor](https://github.com/sponsors/jonschlinkert) to add your logo to this README, or any of [my other projects](https://github.com/jonschlinkert?tab=repositories&q=&type=&language=&sort=stargazers)
|
|
44
|
-
|
|
45
|
-
## Gold Sponsors
|
|
46
|
-
|
|
47
|
-
| [<img src="https://github.com/jonschlinkert/clone-deep/assets/383994/98036489-2cae-48a2-8d29-7dec58ea05c4" alt="https://jaake.tech/" width="100"/>](https://jaake.tech/) |
|
|
48
|
-
|:---:|
|
|
49
|
-
| [https://jaake.tech/](https://jaake.tech/) |
|
|
50
|
-
|
|
51
|
-
<br />
|
|
52
|
-
|
|
53
45
|
## Quick Start
|
|
54
46
|
|
|
55
47
|
Assuming you want to add a TOC to README.md:
|
|
@@ -106,6 +98,74 @@ _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](
|
|
|
106
98
|
(to specify a tab, use the bash-escaped $'\t')
|
|
107
99
|
```
|
|
108
100
|
|
|
101
|
+
## SPA
|
|
102
|
+
|
|
103
|
+
Create a table of contents in a client-side-rendered app.
|
|
104
|
+
|
|
105
|
+
Pass `toc` an element, or a ref to an element, instead of a markdown
|
|
106
|
+
string. It reads the headings inside that element, gives each heading
|
|
107
|
+
without an `id` a slug `id`, and returns the same result object as the
|
|
108
|
+
markdown version (see [API](#api)). Options like `maxdepth` work the same
|
|
109
|
+
way, and `json` only includes headings within `maxdepth`.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { toc, type TocHeading } from '@substrate-system/markdown-toc'
|
|
113
|
+
import { html } from 'htm/preact'
|
|
114
|
+
import { type FunctionComponent } from 'preact'
|
|
115
|
+
import { useLayoutEffect, useRef, useState } from 'preact/hooks'
|
|
116
|
+
|
|
117
|
+
export const Main:FunctionComponent = function () {
|
|
118
|
+
const div = useRef<HTMLDivElement>(null)
|
|
119
|
+
const [tocJson, setTocJson] = useState<TocHeading[]>([])
|
|
120
|
+
|
|
121
|
+
// after the first render, so the headings are in the DOM
|
|
122
|
+
useLayoutEffect(() => {
|
|
123
|
+
if (!div.current) return
|
|
124
|
+
setTocJson(toc(div, { maxdepth: 3 }).json)
|
|
125
|
+
}, [])
|
|
126
|
+
|
|
127
|
+
return html`<div ref=${div} class="example">
|
|
128
|
+
<h2>Contents</h2>
|
|
129
|
+
<ul>
|
|
130
|
+
${tocJson.map((t) => {
|
|
131
|
+
return html`<li><a href="#${t.slug}">${t.content}</a></li>`
|
|
132
|
+
})}
|
|
133
|
+
</ul>
|
|
134
|
+
<h2>Example</h2>
|
|
135
|
+
<h3>Level 3</h3>
|
|
136
|
+
hello
|
|
137
|
+
<h4>Level 4</h4>
|
|
138
|
+
</div>`
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Preact
|
|
143
|
+
|
|
144
|
+
Because I like `preact`, this includes a ready-to-use preact component.
|
|
145
|
+
`preact` is an optional peer dependency.
|
|
146
|
+
|
|
147
|
+
`<TOC />` renders a `<nav>` with a nested list of links to the headings
|
|
148
|
+
that come *after* it in the document, so a heading above it (like the
|
|
149
|
+
`Contents` title here) is left out. It takes the same options as `toc`,
|
|
150
|
+
as props. The list updates when headings are added, removed, or changed.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { TOC } from '@substrate-system/markdown-toc/preact'
|
|
154
|
+
import { type FunctionComponent } from 'preact'
|
|
155
|
+
|
|
156
|
+
export const Main:FunctionComponent = function () {
|
|
157
|
+
return <main>
|
|
158
|
+
<details>
|
|
159
|
+
<summary><h2>Contents</h2></summary>
|
|
160
|
+
<TOC maxdepth={3} />
|
|
161
|
+
</details>
|
|
162
|
+
|
|
163
|
+
<h2>Hello Table of Contents</h2>
|
|
164
|
+
<h3>more testing</h3>
|
|
165
|
+
</main>
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
109
169
|
## Highlights
|
|
110
170
|
|
|
111
171
|
**Features**
|
|
@@ -126,7 +186,7 @@ _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](
|
|
|
126
186
|
## Usage
|
|
127
187
|
|
|
128
188
|
```js
|
|
129
|
-
import {toc} from '@substrate-system/markdown-toc'
|
|
189
|
+
import { toc } from '@substrate-system/markdown-toc'
|
|
130
190
|
|
|
131
191
|
toc('# One\n\n# Two').content;
|
|
132
192
|
// Results in:
|
|
@@ -147,7 +207,7 @@ To allow customization of the output, an object is returned with the following p
|
|
|
147
207
|
Use as a [remarkable](https://github.com/jonschlinkert/remarkable) plugin.
|
|
148
208
|
|
|
149
209
|
```js
|
|
150
|
-
import {Remarkable, toc} from '@substrate-system/markdown-toc'
|
|
210
|
+
import { Remarkable, toc } from '@substrate-system/markdown-toc'
|
|
151
211
|
|
|
152
212
|
function render(str, options) {
|
|
153
213
|
return new Remarkable()
|
|
@@ -175,7 +235,7 @@ Results in:
|
|
|
175
235
|
Object for creating a custom TOC.
|
|
176
236
|
|
|
177
237
|
```js
|
|
178
|
-
import {toc} from '@substrate-system/markdown-toc'
|
|
238
|
+
import { toc } from '@substrate-system/markdown-toc'
|
|
179
239
|
|
|
180
240
|
toc('# AAA\n## BBB\n### CCC\nfoo').json;
|
|
181
241
|
|
|
@@ -187,9 +247,12 @@ toc('# AAA\n## BBB\n### CCC\nfoo').json;
|
|
|
187
247
|
|
|
188
248
|
### toc.insert
|
|
189
249
|
|
|
190
|
-
Insert a table of contents immediately after an _opening_ `<!-- toc -->` code
|
|
250
|
+
Insert a table of contents immediately after an _opening_ `<!-- toc -->` code
|
|
251
|
+
comment, or replace an existing TOC if both an _opening_ comment and
|
|
252
|
+
a _closing_ comment (`<!-- tocstop -->`) are found.
|
|
191
253
|
|
|
192
|
-
_(This strategy works well since code comments in markdown are hidden
|
|
254
|
+
_(This strategy works well since code comments in markdown are hidden when_
|
|
255
|
+
_viewed as HTML, like when viewing a README on GitHub README for example)._
|
|
193
256
|
|
|
194
257
|
**Example**
|
|
195
258
|
|
package/dist/dom.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { renderBullets, slugify, titleize } from "./markdown-toc.js";
|
|
4
|
+
const HEADINGS = "h1, h2, h3, h4, h5, h6";
|
|
5
|
+
function domToc(target, options = {}) {
|
|
6
|
+
const root = resolveTarget(target);
|
|
7
|
+
return headingsToc(Array.from(root.querySelectorAll(HEADINGS)), options);
|
|
8
|
+
}
|
|
9
|
+
__name(domToc, "domToc");
|
|
10
|
+
function headingsToc(elements, options = {}) {
|
|
11
|
+
const maxdepth = options.maxdepth ?? 6;
|
|
12
|
+
const headings = elements.filter((el) => headingLevel(el) <= maxdepth);
|
|
13
|
+
const used = new Set(headings.map((el) => el.id).filter(Boolean));
|
|
14
|
+
const seen = {};
|
|
15
|
+
const json = [];
|
|
16
|
+
const tokens = [];
|
|
17
|
+
headings.forEach((el, i) => {
|
|
18
|
+
const content2 = (el.textContent ?? "").trim();
|
|
19
|
+
const seenCount = seen[content2] ?? 0;
|
|
20
|
+
seen[content2] = seenCount + 1;
|
|
21
|
+
if (!el.id) {
|
|
22
|
+
el.id = uniqueSlug(content2, seenCount, used, options);
|
|
23
|
+
used.add(el.id);
|
|
24
|
+
}
|
|
25
|
+
const slug = el.id;
|
|
26
|
+
const lvl = headingLevel(el);
|
|
27
|
+
const text = titleize(content2, options);
|
|
28
|
+
json.push({ content: content2, slug, lvl, i, seen: seenCount });
|
|
29
|
+
tokens.push({
|
|
30
|
+
type: "inline",
|
|
31
|
+
content: `[${text}](#${encodeURIComponent(slug)})`,
|
|
32
|
+
lvl,
|
|
33
|
+
i,
|
|
34
|
+
seen: seenCount,
|
|
35
|
+
slug
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
const highest = tokens.reduce((min, token) => {
|
|
39
|
+
return Math.min(min, token.lvl ?? 0);
|
|
40
|
+
}, tokens.length ? Number.POSITIVE_INFINITY : 0);
|
|
41
|
+
const content = renderBullets(
|
|
42
|
+
options.firsth1 === false ? tokens.slice(1) : tokens,
|
|
43
|
+
{ ...options, highest }
|
|
44
|
+
) + (options.append ?? "");
|
|
45
|
+
return { content, highest, json, tokens };
|
|
46
|
+
}
|
|
47
|
+
__name(headingsToc, "headingsToc");
|
|
48
|
+
function headingLevel(el) {
|
|
49
|
+
return Number(el.tagName.slice(1));
|
|
50
|
+
}
|
|
51
|
+
__name(headingLevel, "headingLevel");
|
|
52
|
+
function resolveTarget(target) {
|
|
53
|
+
if ("current" in target) {
|
|
54
|
+
if (!target.current) {
|
|
55
|
+
throw new TypeError("toc: the ref has no element yet");
|
|
56
|
+
}
|
|
57
|
+
return target.current;
|
|
58
|
+
}
|
|
59
|
+
return target;
|
|
60
|
+
}
|
|
61
|
+
__name(resolveTarget, "resolveTarget");
|
|
62
|
+
function uniqueSlug(content, seenCount, used, options) {
|
|
63
|
+
let num = seenCount;
|
|
64
|
+
let slug = slugify(content, { ...options, num });
|
|
65
|
+
while (used.has(slug)) {
|
|
66
|
+
num++;
|
|
67
|
+
const next = slugify(content, { ...options, num });
|
|
68
|
+
if (next === slug) break;
|
|
69
|
+
slug = next;
|
|
70
|
+
}
|
|
71
|
+
return slug;
|
|
72
|
+
}
|
|
73
|
+
__name(uniqueSlug, "uniqueSlug");
|
|
74
|
+
export {
|
|
75
|
+
HEADINGS,
|
|
76
|
+
domToc,
|
|
77
|
+
headingLevel,
|
|
78
|
+
headingsToc
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=dom.js.map
|
package/dist/dom.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/dom.ts"],
|
|
4
|
+
"sourcesContent": ["import { renderBullets, slugify, titleize } from './markdown-toc.js'\nimport type {\n TocHeading,\n TocOptions,\n TocResult,\n TocToken,\n} from './types.js'\n\n/**\n * Something we can read headings from: an element, a document, or a\n * ref object like the one returned by preact's `useRef`.\n */\nexport type TocTarget = ParentNode|{ readonly current:ParentNode|null }\n\nexport const HEADINGS = 'h1, h2, h3, h4, h5, h6'\n\n/**\n * Create a table of contents from the headings inside `target`.\n * Headings without an `id` get one, so the generated links work.\n */\nexport function domToc (\n target:TocTarget,\n options:Readonly<TocOptions> = {},\n):TocResult {\n const root = resolveTarget(target)\n return headingsToc(Array.from(root.querySelectorAll(HEADINGS)), options)\n}\n\n/**\n * Create a table of contents from a list of heading elements.\n */\nexport function headingsToc (\n elements:ReadonlyArray<Element>,\n options:Readonly<TocOptions> = {},\n):TocResult {\n const maxdepth = options.maxdepth ?? 6\n const headings = elements.filter(el => headingLevel(el) <= maxdepth)\n const used = new Set(headings.map(el => el.id).filter(Boolean))\n const seen:Record<string, number> = {}\n const json:Array<TocHeading> = []\n const tokens:Array<TocToken> = []\n\n headings.forEach((el, i) => {\n const content = (el.textContent ?? '').trim()\n const seenCount = seen[content] ?? 0\n seen[content] = seenCount + 1\n\n if (!el.id) {\n el.id = uniqueSlug(content, seenCount, used, options)\n used.add(el.id)\n }\n\n const slug = el.id\n const lvl = headingLevel(el)\n const text = titleize(content, options)\n json.push({ content, slug, lvl, i, seen:seenCount })\n tokens.push({\n type:'inline',\n content:`[${text}](#${encodeURIComponent(slug)})`,\n lvl,\n i,\n seen:seenCount,\n slug,\n })\n })\n\n const highest = tokens.reduce((min, token) => {\n return Math.min(min, token.lvl ?? 0)\n }, tokens.length ? Number.POSITIVE_INFINITY : 0)\n const content = renderBullets(\n options.firsth1 === false ? tokens.slice(1) : tokens,\n { ...options, highest }\n ) + (options.append ?? '')\n\n return { content, highest, json, tokens }\n}\n\n/**\n * Get the heading level from the tag name, `h3` -> 3.\n */\nexport function headingLevel (el:Element):number {\n return Number(el.tagName.slice(1))\n}\n\nfunction resolveTarget (target:TocTarget):ParentNode {\n if ('current' in target) {\n if (!target.current) {\n throw new TypeError('toc: the ref has no element yet')\n }\n return target.current\n }\n return target\n}\n\n/**\n * Slugify the heading text, then bump the number suffix until the slug\n * does not collide with an id that is already in use.\n */\nfunction uniqueSlug (\n content:string,\n seenCount:number,\n used:ReadonlySet<string>,\n options:Readonly<TocOptions>,\n):string {\n let num = seenCount\n let slug = slugify(content, { ...options, num })\n while (used.has(slug)) {\n num++\n const next = slugify(content, { ...options, num })\n // a custom slugify, or `slugify:false`, may ignore `num`\n if (next === slug) break\n slug = next\n }\n return slug\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,SAAS,eAAe,SAAS,gBAAgB;AAc1C,MAAM,WAAW;AAMjB,SAAS,OACZ,QACA,UAA+B,CAAC,GACxB;AACR,QAAM,OAAO,cAAc,MAAM;AACjC,SAAO,YAAY,MAAM,KAAK,KAAK,iBAAiB,QAAQ,CAAC,GAAG,OAAO;AAC3E;AANgB;AAWT,SAAS,YACZ,UACA,UAA+B,CAAC,GACxB;AACR,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,WAAW,SAAS,OAAO,QAAM,aAAa,EAAE,KAAK,QAAQ;AACnE,QAAM,OAAO,IAAI,IAAI,SAAS,IAAI,QAAM,GAAG,EAAE,EAAE,OAAO,OAAO,CAAC;AAC9D,QAAM,OAA8B,CAAC;AACrC,QAAM,OAAyB,CAAC;AAChC,QAAM,SAAyB,CAAC;AAEhC,WAAS,QAAQ,CAAC,IAAI,MAAM;AACxB,UAAMA,YAAW,GAAG,eAAe,IAAI,KAAK;AAC5C,UAAM,YAAY,KAAKA,QAAO,KAAK;AACnC,SAAKA,QAAO,IAAI,YAAY;AAE5B,QAAI,CAAC,GAAG,IAAI;AACR,SAAG,KAAK,WAAWA,UAAS,WAAW,MAAM,OAAO;AACpD,WAAK,IAAI,GAAG,EAAE;AAAA,IAClB;AAEA,UAAM,OAAO,GAAG;AAChB,UAAM,MAAM,aAAa,EAAE;AAC3B,UAAM,OAAO,SAASA,UAAS,OAAO;AACtC,SAAK,KAAK,EAAE,SAAAA,UAAS,MAAM,KAAK,GAAG,MAAK,UAAU,CAAC;AACnD,WAAO,KAAK;AAAA,MACR,MAAK;AAAA,MACL,SAAQ,IAAI,IAAI,MAAM,mBAAmB,IAAI,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL;AAAA,IACJ,CAAC;AAAA,EACL,CAAC;AAED,QAAM,UAAU,OAAO,OAAO,CAAC,KAAK,UAAU;AAC1C,WAAO,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC;AAAA,EACvC,GAAG,OAAO,SAAS,OAAO,oBAAoB,CAAC;AAC/C,QAAM,UAAU;AAAA,IACZ,QAAQ,YAAY,QAAQ,OAAO,MAAM,CAAC,IAAI;AAAA,IAC9C,EAAE,GAAG,SAAS,QAAQ;AAAA,EAC1B,KAAK,QAAQ,UAAU;AAEvB,SAAO,EAAE,SAAS,SAAS,MAAM,OAAO;AAC5C;AA5CgB;AAiDT,SAAS,aAAc,IAAmB;AAC7C,SAAO,OAAO,GAAG,QAAQ,MAAM,CAAC,CAAC;AACrC;AAFgB;AAIhB,SAAS,cAAe,QAA6B;AACjD,MAAI,aAAa,QAAQ;AACrB,QAAI,CAAC,OAAO,SAAS;AACjB,YAAM,IAAI,UAAU,iCAAiC;AAAA,IACzD;AACA,WAAO,OAAO;AAAA,EAClB;AACA,SAAO;AACX;AARS;AAcT,SAAS,WACL,SACA,WACA,MACA,SACK;AACL,MAAI,MAAM;AACV,MAAI,OAAO,QAAQ,SAAS,EAAE,GAAG,SAAS,IAAI,CAAC;AAC/C,SAAO,KAAK,IAAI,IAAI,GAAG;AACnB;AACA,UAAM,OAAO,QAAQ,SAAS,EAAE,GAAG,SAAS,IAAI,CAAC;AAEjD,QAAI,SAAS,KAAM;AACnB,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAhBS;",
|
|
6
|
+
"names": ["content"]
|
|
7
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -13,8 +13,9 @@ import {
|
|
|
13
13
|
titleize as titleizeHeading
|
|
14
14
|
} from "./markdown-toc.js";
|
|
15
15
|
import { insertMarkdown } from "./insert-markdown.js";
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
import { domToc } from "./dom.js";
|
|
17
|
+
function toc(source, options = {}) {
|
|
18
|
+
return typeof source === "string" ? generateToc(source, options) : domToc(source, options);
|
|
18
19
|
}
|
|
19
20
|
__name(toc, "toc");
|
|
20
21
|
const utils = {
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import Remarkable from 'remarkable'\nimport {\n generatePlugin,\n generateToc,\n getHighest,\n getTitle,\n linkify as linkifyHeading,\n renderBullets,\n slugify as slugifyHeading,\n strip as stripHeading,\n titleize as titleizeHeading,\n} from './markdown-toc.js'\nimport { insertMarkdown } from './insert-markdown.js'\nimport type { TocOptions, TocResult, TocUtils } from './types.js'\n\nexport type * from './types.js'\nexport { Remarkable }\nexport {\n generatePlugin as plugin,\n generateToc,\n getHighest,\n getTitle,\n insertMarkdown,\n linkifyHeading as linkify,\n renderBullets,\n slugifyHeading as slugify,\n stripHeading as strip,\n titleizeHeading as titleize,\n}\nexport { renderBullets as bullets }\n\nexport function toc (\n markdown:string,\n options:Readonly<TocOptions> = {},\n):TocResult {\n return generateToc(
|
|
5
|
-
"mappings": ";;AAAA,OAAO,gBAAgB;AACvB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,OACT;AACP,SAAS,sBAAsB;
|
|
4
|
+
"sourcesContent": ["import Remarkable from 'remarkable'\nimport {\n generatePlugin,\n generateToc,\n getHighest,\n getTitle,\n linkify as linkifyHeading,\n renderBullets,\n slugify as slugifyHeading,\n strip as stripHeading,\n titleize as titleizeHeading,\n} from './markdown-toc.js'\nimport { insertMarkdown } from './insert-markdown.js'\nimport { domToc, type TocTarget } from './dom.js'\nimport type { TocOptions, TocResult, TocUtils } from './types.js'\n\nexport type * from './types.js'\nexport type { TocTarget }\nexport { Remarkable }\nexport {\n generatePlugin as plugin,\n generateToc,\n getHighest,\n getTitle,\n insertMarkdown,\n linkifyHeading as linkify,\n renderBullets,\n slugifyHeading as slugify,\n stripHeading as strip,\n titleizeHeading as titleize,\n}\nexport { renderBullets as bullets }\n\n/**\n * Create a table of contents from a markdown string, or, in a browser,\n * from the headings inside an element (or a ref to an element).\n */\nexport function toc (\n markdown:string,\n options?:Readonly<TocOptions>,\n):TocResult\nexport function toc (\n target:TocTarget,\n options?:Readonly<TocOptions>,\n):TocResult\nexport function toc (\n source:string|TocTarget,\n options:Readonly<TocOptions> = {},\n):TocResult {\n return typeof source === 'string' ?\n generateToc(source, options) :\n domToc(source, options)\n}\n\nexport const utils:TocUtils = {\n Remarkable,\n getTitle,\n slugify:slugifyHeading,\n strip:stripHeading,\n titleize:titleizeHeading,\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,OAAO,gBAAgB;AACvB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,OACT;AACP,SAAS,sBAAsB;AAC/B,SAAS,cAA8B;AAgChC,SAAS,IACZ,QACA,UAA+B,CAAC,GACxB;AACR,SAAO,OAAO,WAAW,WACrB,YAAY,QAAQ,OAAO,IAC3B,OAAO,QAAQ,OAAO;AAC9B;AAPgB;AAST,MAAM,QAAiB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,SAAQ;AAAA,EACR,OAAM;AAAA,EACN,UAAS;AACb;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/meta.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"inputs": {
|
|
3
3
|
"src/index.ts": {
|
|
4
|
-
"bytes":
|
|
4
|
+
"bytes": 1507,
|
|
5
5
|
"imports": [],
|
|
6
6
|
"format": "esm"
|
|
7
7
|
},
|
|
@@ -19,6 +19,16 @@
|
|
|
19
19
|
"bytes": 1454,
|
|
20
20
|
"imports": [],
|
|
21
21
|
"format": "esm"
|
|
22
|
+
},
|
|
23
|
+
"src/dom.ts": {
|
|
24
|
+
"bytes": 3320,
|
|
25
|
+
"imports": [],
|
|
26
|
+
"format": "esm"
|
|
27
|
+
},
|
|
28
|
+
"src/preact.ts": {
|
|
29
|
+
"bytes": 3742,
|
|
30
|
+
"imports": [],
|
|
31
|
+
"format": "esm"
|
|
22
32
|
}
|
|
23
33
|
},
|
|
24
34
|
"outputs": {
|
|
@@ -26,7 +36,7 @@
|
|
|
26
36
|
"imports": [],
|
|
27
37
|
"exports": [],
|
|
28
38
|
"inputs": {},
|
|
29
|
-
"bytes":
|
|
39
|
+
"bytes": 2059
|
|
30
40
|
},
|
|
31
41
|
"dist/index.js": {
|
|
32
42
|
"imports": [
|
|
@@ -44,6 +54,11 @@
|
|
|
44
54
|
"path": "./insert-markdown.js",
|
|
45
55
|
"kind": "import-statement",
|
|
46
56
|
"external": true
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"path": "./dom.js",
|
|
60
|
+
"kind": "import-statement",
|
|
61
|
+
"external": true
|
|
47
62
|
}
|
|
48
63
|
],
|
|
49
64
|
"exports": [
|
|
@@ -65,10 +80,10 @@
|
|
|
65
80
|
"entryPoint": "src/index.ts",
|
|
66
81
|
"inputs": {
|
|
67
82
|
"src/index.ts": {
|
|
68
|
-
"bytesInOutput":
|
|
83
|
+
"bytesInOutput": 629
|
|
69
84
|
}
|
|
70
85
|
},
|
|
71
|
-
"bytes":
|
|
86
|
+
"bytes": 1079
|
|
72
87
|
},
|
|
73
88
|
"dist/cli.js.map": {
|
|
74
89
|
"imports": [],
|
|
@@ -172,6 +187,74 @@
|
|
|
172
187
|
}
|
|
173
188
|
},
|
|
174
189
|
"bytes": 1518
|
|
190
|
+
},
|
|
191
|
+
"dist/dom.js.map": {
|
|
192
|
+
"imports": [],
|
|
193
|
+
"exports": [],
|
|
194
|
+
"inputs": {},
|
|
195
|
+
"bytes": 5277
|
|
196
|
+
},
|
|
197
|
+
"dist/dom.js": {
|
|
198
|
+
"imports": [
|
|
199
|
+
{
|
|
200
|
+
"path": "./markdown-toc.js",
|
|
201
|
+
"kind": "import-statement",
|
|
202
|
+
"external": true
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"exports": [
|
|
206
|
+
"HEADINGS",
|
|
207
|
+
"domToc",
|
|
208
|
+
"headingLevel",
|
|
209
|
+
"headingsToc"
|
|
210
|
+
],
|
|
211
|
+
"entryPoint": "src/dom.ts",
|
|
212
|
+
"inputs": {
|
|
213
|
+
"src/dom.ts": {
|
|
214
|
+
"bytesInOutput": 2254
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"bytes": 2479
|
|
218
|
+
},
|
|
219
|
+
"dist/preact.js.map": {
|
|
220
|
+
"imports": [],
|
|
221
|
+
"exports": [],
|
|
222
|
+
"inputs": {},
|
|
223
|
+
"bytes": 6030
|
|
224
|
+
},
|
|
225
|
+
"dist/preact.js": {
|
|
226
|
+
"imports": [
|
|
227
|
+
{
|
|
228
|
+
"path": "preact",
|
|
229
|
+
"kind": "import-statement",
|
|
230
|
+
"external": true
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"path": "preact/hooks",
|
|
234
|
+
"kind": "import-statement",
|
|
235
|
+
"external": true
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"path": "./dom.js",
|
|
239
|
+
"kind": "import-statement",
|
|
240
|
+
"external": true
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"path": "./markdown-toc.js",
|
|
244
|
+
"kind": "import-statement",
|
|
245
|
+
"external": true
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"exports": [
|
|
249
|
+
"TOC"
|
|
250
|
+
],
|
|
251
|
+
"entryPoint": "src/preact.ts",
|
|
252
|
+
"inputs": {
|
|
253
|
+
"src/preact.ts": {
|
|
254
|
+
"bytesInOutput": 2680
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"bytes": 2862
|
|
175
258
|
}
|
|
176
259
|
}
|
|
177
260
|
}
|
package/dist/preact.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { h } from "preact";
|
|
4
|
+
import { useLayoutEffect, useRef, useState } from "preact/hooks";
|
|
5
|
+
import { HEADINGS, headingsToc } from "./dom.js";
|
|
6
|
+
import { titleize } from "./markdown-toc.js";
|
|
7
|
+
const TOC = /* @__PURE__ */ __name(function TOC2(props) {
|
|
8
|
+
const { class: className, children: _children, ...options } = props;
|
|
9
|
+
const nav = useRef(null);
|
|
10
|
+
const latestOptions = useRef(options);
|
|
11
|
+
latestOptions.current = options;
|
|
12
|
+
const update = useRef(() => {
|
|
13
|
+
});
|
|
14
|
+
const [headings, setHeadings] = useState([]);
|
|
15
|
+
useLayoutEffect(() => {
|
|
16
|
+
const el = nav.current;
|
|
17
|
+
if (!el) return;
|
|
18
|
+
update.current = () => {
|
|
19
|
+
const next = headingsToc(
|
|
20
|
+
headingsAfter(el),
|
|
21
|
+
latestOptions.current
|
|
22
|
+
).json;
|
|
23
|
+
setHeadings((prev) => isSame(prev, next) ? prev : next);
|
|
24
|
+
};
|
|
25
|
+
const observer = new MutationObserver(() => update.current());
|
|
26
|
+
observer.observe(el.ownerDocument.body, {
|
|
27
|
+
childList: true,
|
|
28
|
+
subtree: true,
|
|
29
|
+
characterData: true
|
|
30
|
+
});
|
|
31
|
+
return () => {
|
|
32
|
+
observer.disconnect();
|
|
33
|
+
update.current = () => {
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
}, []);
|
|
37
|
+
useLayoutEffect(() => update.current());
|
|
38
|
+
return h("nav", {
|
|
39
|
+
ref: nav,
|
|
40
|
+
class: className,
|
|
41
|
+
"aria-label": "Table of contents"
|
|
42
|
+
}, headings.length ? renderList(toTree(headings)) : null);
|
|
43
|
+
}, "TOC");
|
|
44
|
+
function headingsAfter(el) {
|
|
45
|
+
const all = Array.from(el.ownerDocument.querySelectorAll(HEADINGS));
|
|
46
|
+
return all.filter((heading) => {
|
|
47
|
+
const position = el.compareDocumentPosition(heading);
|
|
48
|
+
return Boolean(position & Node.DOCUMENT_POSITION_FOLLOWING) && !el.contains(heading);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
__name(headingsAfter, "headingsAfter");
|
|
52
|
+
function toTree(headings) {
|
|
53
|
+
const roots = [];
|
|
54
|
+
const stack = [];
|
|
55
|
+
for (const heading of headings) {
|
|
56
|
+
const node = { heading, children: [] };
|
|
57
|
+
while (stack.length && stack[stack.length - 1].heading.lvl >= heading.lvl) {
|
|
58
|
+
stack.pop();
|
|
59
|
+
}
|
|
60
|
+
const parent = stack[stack.length - 1];
|
|
61
|
+
if (parent) parent.children.push(node);
|
|
62
|
+
else roots.push(node);
|
|
63
|
+
stack.push(node);
|
|
64
|
+
}
|
|
65
|
+
return roots;
|
|
66
|
+
}
|
|
67
|
+
__name(toTree, "toTree");
|
|
68
|
+
function renderList(nodes) {
|
|
69
|
+
return h("ul", null, nodes.map(({ heading, children }) => {
|
|
70
|
+
return h(
|
|
71
|
+
"li",
|
|
72
|
+
{ key: heading.slug },
|
|
73
|
+
h(
|
|
74
|
+
"a",
|
|
75
|
+
{ href: "#" + encodeURIComponent(heading.slug) },
|
|
76
|
+
titleize(heading.content)
|
|
77
|
+
),
|
|
78
|
+
children.length ? renderList(children) : null
|
|
79
|
+
);
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
__name(renderList, "renderList");
|
|
83
|
+
function isSame(a, b) {
|
|
84
|
+
return a.length === b.length && a.every((heading, i) => {
|
|
85
|
+
const other = b[i];
|
|
86
|
+
return heading.slug === other.slug && heading.content === other.content && heading.lvl === other.lvl;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
__name(isSame, "isSame");
|
|
90
|
+
export {
|
|
91
|
+
TOC
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=preact.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/preact.ts"],
|
|
4
|
+
"sourcesContent": ["import { h, type FunctionComponent, type VNode } from 'preact'\nimport { useLayoutEffect, useRef, useState } from 'preact/hooks'\nimport { HEADINGS, headingsToc } from './dom.js'\nimport { titleize } from './markdown-toc.js'\nimport type { TocHeading, TocOptions } from './types.js'\n\nexport type TocProps = TocOptions&{\n class?:string;\n}\n\ntype TocNode = {\n heading:TocHeading;\n children:TocNode[];\n}\n\n/**\n * Render a nested list of links to the headings that come after this\n * component in the document. Headings without an `id` get one. The list\n * updates when the document changes.\n */\nexport const TOC:FunctionComponent<TocProps> = function TOC (props) {\n const { class:className, children:_children, ...options } = props\n const nav = useRef<HTMLElement>(null)\n const latestOptions = useRef<TocOptions>(options)\n latestOptions.current = options\n const update = useRef<() => void>(() => {})\n const [headings, setHeadings] = useState<TocHeading[]>([])\n\n useLayoutEffect(() => {\n const el = nav.current\n if (!el) return\n\n update.current = () => {\n const next = headingsToc(\n headingsAfter(el),\n latestOptions.current\n ).json\n setHeadings(prev => isSame(prev, next) ? prev : next)\n }\n\n // Watch structure and text only. Adding an `id` is an attribute\n // change, so it does not trigger another update.\n const observer = new MutationObserver(() => update.current())\n observer.observe(el.ownerDocument.body, {\n childList:true,\n subtree:true,\n characterData:true,\n })\n\n return () => {\n observer.disconnect()\n update.current = () => {}\n }\n }, [])\n\n // re-check after every render, in case the options changed\n useLayoutEffect(() => update.current())\n\n return h('nav', {\n ref:nav,\n class:className,\n 'aria-label':'Table of contents',\n }, headings.length ? renderList(toTree(headings)) : null)\n}\n\n/**\n * Headings that come after `el` in document order.\n */\nfunction headingsAfter (el:Element):Element[] {\n const all = Array.from(el.ownerDocument.querySelectorAll(HEADINGS))\n return all.filter(heading => {\n const position = el.compareDocumentPosition(heading)\n return Boolean(position & Node.DOCUMENT_POSITION_FOLLOWING) &&\n !el.contains(heading)\n })\n}\n\n/**\n * Nest each heading under the closest previous heading with a lower\n * level.\n */\nfunction toTree (headings:ReadonlyArray<TocHeading>):TocNode[] {\n const roots:TocNode[] = []\n const stack:TocNode[] = []\n\n for (const heading of headings) {\n const node:TocNode = { heading, children:[] }\n while (stack.length && stack[stack.length - 1]!.heading.lvl >=\n heading.lvl) {\n stack.pop()\n }\n const parent = stack[stack.length - 1]\n if (parent) parent.children.push(node)\n else roots.push(node)\n stack.push(node)\n }\n\n return roots\n}\n\nfunction renderList (nodes:ReadonlyArray<TocNode>):VNode {\n return h('ul', null, nodes.map(({ heading, children }) => {\n return h('li', { key:heading.slug },\n h('a', { href:'#' + encodeURIComponent(heading.slug) },\n titleize(heading.content)),\n children.length ? renderList(children) : null\n )\n }))\n}\n\nfunction isSame (\n a:ReadonlyArray<TocHeading>,\n b:ReadonlyArray<TocHeading>,\n):boolean {\n return a.length === b.length && a.every((heading, i) => {\n const other = b[i]!\n return heading.slug === other.slug &&\n heading.content === other.content &&\n heading.lvl === other.lvl\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["TOC"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TocOptions, TocResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Something we can read headings from: an element, a document, or a
|
|
4
|
+
* ref object like the one returned by preact's `useRef`.
|
|
5
|
+
*/
|
|
6
|
+
export type TocTarget = ParentNode | {
|
|
7
|
+
readonly current: ParentNode | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const HEADINGS = "h1, h2, h3, h4, h5, h6";
|
|
10
|
+
/**
|
|
11
|
+
* Create a table of contents from the headings inside `target`.
|
|
12
|
+
* Headings without an `id` get one, so the generated links work.
|
|
13
|
+
*/
|
|
14
|
+
export declare function domToc(target: TocTarget, options?: Readonly<TocOptions>): TocResult;
|
|
15
|
+
/**
|
|
16
|
+
* Create a table of contents from a list of heading elements.
|
|
17
|
+
*/
|
|
18
|
+
export declare function headingsToc(elements: ReadonlyArray<Element>, options?: Readonly<TocOptions>): TocResult;
|
|
19
|
+
/**
|
|
20
|
+
* Get the heading level from the tag name, `h3` -> 3.
|
|
21
|
+
*/
|
|
22
|
+
export declare function headingLevel(el: Element): number;
|
|
23
|
+
//# sourceMappingURL=dom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/dom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAER,UAAU,EACV,SAAS,EAEZ,MAAM,YAAY,CAAA;AAEnB;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAC;IAAE,QAAQ,CAAC,OAAO,EAAC,UAAU,GAAC,IAAI,CAAA;CAAE,CAAA;AAEvE,eAAO,MAAM,QAAQ,2BAA2B,CAAA;AAEhD;;;GAGG;AACH,wBAAgB,MAAM,CAClB,MAAM,EAAC,SAAS,EAChB,OAAO,GAAC,QAAQ,CAAC,UAAU,CAAM,GACnC,SAAS,CAGV;AAED;;GAEG;AACH,wBAAgB,WAAW,CACvB,QAAQ,EAAC,aAAa,CAAC,OAAO,CAAC,EAC/B,OAAO,GAAC,QAAQ,CAAC,UAAU,CAAM,GACnC,SAAS,CAyCV;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAE,EAAE,EAAC,OAAO,GAAE,MAAM,CAE/C"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import Remarkable from 'remarkable';
|
|
2
2
|
import { generatePlugin, generateToc, getHighest, getTitle, linkify as linkifyHeading, renderBullets, slugify as slugifyHeading, strip as stripHeading, titleize as titleizeHeading } from './markdown-toc.js';
|
|
3
3
|
import { insertMarkdown } from './insert-markdown.js';
|
|
4
|
+
import { type TocTarget } from './dom.js';
|
|
4
5
|
import type { TocOptions, TocResult, TocUtils } from './types.js';
|
|
5
6
|
export type * from './types.js';
|
|
7
|
+
export type { TocTarget };
|
|
6
8
|
export { Remarkable };
|
|
7
9
|
export { generatePlugin as plugin, generateToc, getHighest, getTitle, insertMarkdown, linkifyHeading as linkify, renderBullets, slugifyHeading as slugify, stripHeading as strip, titleizeHeading as titleize, };
|
|
8
10
|
export { renderBullets as bullets };
|
|
11
|
+
/**
|
|
12
|
+
* Create a table of contents from a markdown string, or, in a browser,
|
|
13
|
+
* from the headings inside an element (or a ref to an element).
|
|
14
|
+
*/
|
|
9
15
|
export declare function toc(markdown: string, options?: Readonly<TocOptions>): TocResult;
|
|
16
|
+
export declare function toc(target: TocTarget, options?: Readonly<TocOptions>): TocResult;
|
|
10
17
|
export declare const utils: TocUtils;
|
|
11
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EACH,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,IAAI,cAAc,EACzB,aAAa,EACb,OAAO,IAAI,cAAc,EACzB,KAAK,IAAI,YAAY,EACrB,QAAQ,IAAI,eAAe,EAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEjE,mBAAmB,YAAY,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,CAAA;AACrB,OAAO,EACH,cAAc,IAAI,MAAM,EACxB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,cAAc,EACd,cAAc,IAAI,OAAO,EACzB,aAAa,EACb,cAAc,IAAI,OAAO,EACzB,YAAY,IAAI,KAAK,EACrB,eAAe,IAAI,QAAQ,GAC9B,CAAA;AACD,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAEnC,wBAAgB,GAAG,CACf,QAAQ,EAAC,MAAM,EACf,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EACH,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,IAAI,cAAc,EACzB,aAAa,EACb,OAAO,IAAI,cAAc,EACzB,KAAK,IAAI,YAAY,EACrB,QAAQ,IAAI,eAAe,EAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEjE,mBAAmB,YAAY,CAAA;AAC/B,YAAY,EAAE,SAAS,EAAE,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,CAAA;AACrB,OAAO,EACH,cAAc,IAAI,MAAM,EACxB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,cAAc,EACd,cAAc,IAAI,OAAO,EACzB,aAAa,EACb,cAAc,IAAI,OAAO,EACzB,YAAY,IAAI,KAAK,EACrB,eAAe,IAAI,QAAQ,GAC9B,CAAA;AACD,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAEnC;;;GAGG;AACH,wBAAgB,GAAG,CACf,QAAQ,EAAC,MAAM,EACf,OAAO,CAAC,EAAC,QAAQ,CAAC,UAAU,CAAC,GAC/B,SAAS,CAAA;AACX,wBAAgB,GAAG,CACf,MAAM,EAAC,SAAS,EAChB,OAAO,CAAC,EAAC,QAAQ,CAAC,UAAU,CAAC,GAC/B,SAAS,CAAA;AAUX,eAAO,MAAM,KAAK,EAAC,QAMlB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type FunctionComponent } from 'preact';
|
|
2
|
+
import type { TocOptions } from './types.js';
|
|
3
|
+
export type TocProps = TocOptions & {
|
|
4
|
+
class?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Render a nested list of links to the headings that come after this
|
|
8
|
+
* component in the document. Headings without an `id` get one. The list
|
|
9
|
+
* updates when the document changes.
|
|
10
|
+
*/
|
|
11
|
+
export declare const TOC: FunctionComponent<TocProps>;
|
|
12
|
+
//# sourceMappingURL=preact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preact.d.ts","sourceRoot":"","sources":["../../src/preact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,iBAAiB,EAAc,MAAM,QAAQ,CAAA;AAI9D,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,YAAY,CAAA;AAExD,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAC;IAC9B,KAAK,CAAC,EAAC,MAAM,CAAC;CACjB,CAAA;AAOD;;;;GAIG;AACH,eAAO,MAAM,GAAG,EAAC,iBAAiB,CAAC,QAAQ,CA2C1C,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrate-system/markdown-toc",
|
|
3
3
|
"description": "Generate a markdown TOC (table of contents) with Remarkable.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -20,8 +20,10 @@
|
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"lint": "eslint \"./**/*.{ts,js}\"",
|
|
23
|
-
"test": "
|
|
24
|
-
"
|
|
23
|
+
"test": "npm run test:node && npm run test:browser",
|
|
24
|
+
"test:node": "esbuild test/index.ts --platform=node --format=esm --keep-names --bundle --external:gray-matter --external:remarkable --external:diacritics-map | node --input-type=module | tap-spec",
|
|
25
|
+
"test:browser": "esbuild test/browser.ts --bundle --keep-names | tapout | tap-spec",
|
|
26
|
+
"build-esm": "esbuild src/index.ts src/cli.ts src/markdown-toc.ts src/insert-markdown.ts src/dom.ts src/preact.ts --format=esm --metafile=dist/meta.json --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --sourcemap && tsc --emitDeclarationOnly --project tsconfig.build.json --outDir dist",
|
|
25
27
|
"build": "mkdir -p ./dist && rm -rf ./dist/* && npm run build-esm",
|
|
26
28
|
"preversion": "npm run lint",
|
|
27
29
|
"version": "auto-changelog -p --template keepachangelog --breaking-pattern 'BREAKING CHANGE:' && git add CHANGELOG.md README.md",
|
|
@@ -34,13 +36,25 @@
|
|
|
34
36
|
"gray-matter": "^4.0.3",
|
|
35
37
|
"remarkable": "^1.7.1"
|
|
36
38
|
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"preact": "^10.0.0 || ^11.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"preact": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
37
47
|
"devDependencies": {
|
|
48
|
+
"@substrate-system/redeye": "^0.1.7",
|
|
49
|
+
"@substrate-system/tapout": "^0.1.1",
|
|
38
50
|
"@substrate-system/tapzero": "^0.10.16",
|
|
39
51
|
"@types/node": "^24.0.3",
|
|
40
52
|
"auto-changelog": "^2.6.1",
|
|
41
53
|
"esbuild": "^0.28.2",
|
|
42
54
|
"eslint": "^10.10.0",
|
|
55
|
+
"htm": "^3.1.1",
|
|
43
56
|
"newneostandard": "^0.14.3",
|
|
57
|
+
"preact": "^11.2.0",
|
|
44
58
|
"tap-spec": "^5.0.0",
|
|
45
59
|
"typescript": "^6.0.3",
|
|
46
60
|
"typescript-eslint": "^8.70.0"
|
|
@@ -50,5 +64,8 @@
|
|
|
50
64
|
"repository": "substrate-system/markdown-toc",
|
|
51
65
|
"engines": {
|
|
52
66
|
"node": ">=18"
|
|
67
|
+
},
|
|
68
|
+
"allowScripts": {
|
|
69
|
+
"esbuild": true
|
|
53
70
|
}
|
|
54
71
|
}
|