@substrate-system/markdown-toc 1.3.5 → 1.3.7
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 +12 -9
- package/dist/cli.js +114 -0
- package/dist/cli.js.map +7 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +7 -0
- package/dist/insert-markdown.js +37 -0
- package/dist/insert-markdown.js.map +7 -0
- package/dist/markdown-toc.js +230 -0
- package/dist/markdown-toc.js.map +7 -0
- package/dist/meta.json +177 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/insert-markdown.d.ts +3 -0
- package/dist/src/insert-markdown.d.ts.map +1 -0
- package/dist/src/markdown-toc.d.ts +11 -0
- package/dist/src/markdown-toc.d.ts.map +1 -0
- package/dist/src/types.d.ts +67 -0
- package/dist/src/types.d.ts.map +1 -0
- package/package.json +40 -107
- package/cli.js +0 -78
- package/index.js +0 -255
- package/lib/insert.js +0 -67
- package/lib/utils.js +0 -86
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ This is a fork of [jonschlinkert/markdown-toc](https://github.com/jonschlinkert/
|
|
|
35
35
|
Install with [npm](https://www.npmjs.com/):
|
|
36
36
|
|
|
37
37
|
```sh
|
|
38
|
-
npm i
|
|
38
|
+
npm i @substrate-system/markdown-toc
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
# Sponsors
|
|
@@ -54,7 +54,7 @@ Thanks to the following companies, organizations, and individuals for supporting
|
|
|
54
54
|
|
|
55
55
|
Assuming you want to add a TOC to README.md:
|
|
56
56
|
|
|
57
|
-
1. `$ npm install -g markdown-toc`
|
|
57
|
+
1. `$ npm install -g @substrate-system/markdown-toc`
|
|
58
58
|
2. Edit README.md and insert the following line where you want the TOC inserted:<br />`<!-- toc -->`
|
|
59
59
|
3. `$ markdown-toc -i README.md`
|
|
60
60
|
|
|
@@ -126,7 +126,7 @@ _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](
|
|
|
126
126
|
## Usage
|
|
127
127
|
|
|
128
128
|
```js
|
|
129
|
-
|
|
129
|
+
import {toc} from '@substrate-system/markdown-toc'
|
|
130
130
|
|
|
131
131
|
toc('# One\n\n# Two').content;
|
|
132
132
|
// Results in:
|
|
@@ -147,8 +147,7 @@ To allow customization of the output, an object is returned with the following p
|
|
|
147
147
|
Use as a [remarkable](https://github.com/jonschlinkert/remarkable) plugin.
|
|
148
148
|
|
|
149
149
|
```js
|
|
150
|
-
|
|
151
|
-
var toc = require('markdown-toc');
|
|
150
|
+
import {Remarkable, toc} from '@substrate-system/markdown-toc'
|
|
152
151
|
|
|
153
152
|
function render(str, options) {
|
|
154
153
|
return new Remarkable()
|
|
@@ -176,6 +175,8 @@ Results in:
|
|
|
176
175
|
Object for creating a custom TOC.
|
|
177
176
|
|
|
178
177
|
```js
|
|
178
|
+
import {toc} from '@substrate-system/markdown-toc'
|
|
179
|
+
|
|
179
180
|
toc('# AAA\n## BBB\n### CCC\nfoo').json;
|
|
180
181
|
|
|
181
182
|
// results in
|
|
@@ -226,7 +227,7 @@ This is x y z.
|
|
|
226
227
|
As a convenience to folks who wants to create a custom TOC, markdown-toc's internal utility methods are exposed:
|
|
227
228
|
|
|
228
229
|
```js
|
|
229
|
-
|
|
230
|
+
import {toc} from '@substrate-system/markdown-toc'
|
|
230
231
|
```
|
|
231
232
|
|
|
232
233
|
* `toc.bullets()`: render a bullet list from an array of tokens
|
|
@@ -241,7 +242,7 @@ var result = toc('# AAA\n## BBB\n### CCC\nfoo');
|
|
|
241
242
|
var str = '';
|
|
242
243
|
|
|
243
244
|
result.json.forEach(function(heading) {
|
|
244
|
-
str += toc.linkify(heading
|
|
245
|
+
str += toc.linkify(heading);
|
|
245
246
|
});
|
|
246
247
|
```
|
|
247
248
|
|
|
@@ -295,7 +296,9 @@ Default: Basic non-word character replacement.
|
|
|
295
296
|
**Example**
|
|
296
297
|
|
|
297
298
|
```js
|
|
298
|
-
var str = toc('# Some Article', {
|
|
299
|
+
var str = toc('# Some Article', {
|
|
300
|
+
slugify: text => text.toLowerCase().replace(/\s+/g, '-')
|
|
301
|
+
});
|
|
299
302
|
```
|
|
300
303
|
|
|
301
304
|
### options.bullets
|
|
@@ -416,4 +419,4 @@ Released under the [MIT License](LICENSE).
|
|
|
416
419
|
|
|
417
420
|
***
|
|
418
421
|
|
|
419
|
-
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on July 12, 2023._
|
|
422
|
+
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on July 12, 2023._
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { stdin, stderr, stdout } from "node:process";
|
|
6
|
+
import { insertMarkdown, toc } from "./index.js";
|
|
7
|
+
async function main() {
|
|
8
|
+
const args = parseArguments(process.argv.slice(2));
|
|
9
|
+
if (args._.length !== 1) {
|
|
10
|
+
stderr.write(`${usage()}
|
|
11
|
+
`);
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (args.i && args.json) {
|
|
16
|
+
stderr.write("markdown-toc: you cannot use both --json and -i\n");
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (args.i && args._[0] === "-") {
|
|
21
|
+
stderr.write(
|
|
22
|
+
'markdown-toc: you cannot use -i with "-" (stdin) for input\n'
|
|
23
|
+
);
|
|
24
|
+
process.exitCode = 1;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const input = args._[0] === "-" ? await readStdin() : readFileSync(args._[0] ?? "", "utf8");
|
|
28
|
+
if (args.i) {
|
|
29
|
+
const path = args._[0] ?? "";
|
|
30
|
+
writeFileSync(path, insertMarkdown(input, args));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const parsed = toc(input, args);
|
|
34
|
+
if (args.json) {
|
|
35
|
+
stdout.write(`${JSON.stringify(parsed.json, null, 2)}
|
|
36
|
+
`);
|
|
37
|
+
} else {
|
|
38
|
+
stdout.write(parsed.content);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
__name(main, "main");
|
|
42
|
+
function parseArguments(argumentsList) {
|
|
43
|
+
const values = {
|
|
44
|
+
_: [],
|
|
45
|
+
firsth1: true,
|
|
46
|
+
stripHeadingTags: true
|
|
47
|
+
};
|
|
48
|
+
for (let index = 0; index < argumentsList.length; index++) {
|
|
49
|
+
const argument = argumentsList[index];
|
|
50
|
+
const next = argumentsList[index + 1];
|
|
51
|
+
if (argument === "-i") values.i = true;
|
|
52
|
+
else if (argument === "--json") values.json = true;
|
|
53
|
+
else if (argument === "--no-firsth1") values.firsth1 = false;
|
|
54
|
+
else if (argument === "--no-stripHeadingTags") {
|
|
55
|
+
values.stripHeadingTags = false;
|
|
56
|
+
} else if (argument === "--append" && next) {
|
|
57
|
+
values.append = next;
|
|
58
|
+
index++;
|
|
59
|
+
} else if (argument === "--bullets" && next) {
|
|
60
|
+
values.bullets = [...values.bullets ?? [], next];
|
|
61
|
+
index++;
|
|
62
|
+
} else if (argument === "--indent" && next) {
|
|
63
|
+
values.indent = next;
|
|
64
|
+
index++;
|
|
65
|
+
} else if (argument === "--maxdepth" && next) {
|
|
66
|
+
values.maxdepth = Number.parseInt(next, 10);
|
|
67
|
+
index++;
|
|
68
|
+
} else if (argument === "-") {
|
|
69
|
+
values._.push(argument);
|
|
70
|
+
} else if (argument?.startsWith("-")) {
|
|
71
|
+
continue;
|
|
72
|
+
} else if (argument) {
|
|
73
|
+
values._.push(argument);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return values;
|
|
77
|
+
}
|
|
78
|
+
__name(parseArguments, "parseArguments");
|
|
79
|
+
function readStdin() {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
const chunks = [];
|
|
82
|
+
stdin.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
83
|
+
stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
84
|
+
stdin.on("error", reject);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
__name(readStdin, "readStdin");
|
|
88
|
+
function usage() {
|
|
89
|
+
return [
|
|
90
|
+
"Usage: markdown-toc [options] <input>",
|
|
91
|
+
"",
|
|
92
|
+
' input: The Markdown file to parse, or "-" for stdin.',
|
|
93
|
+
" -i: Edit the input file and inject the TOC.",
|
|
94
|
+
" --json: Print the TOC in JSON format.",
|
|
95
|
+
" --append: Append a string to the TOC.",
|
|
96
|
+
" --bullets: Set the bullet; may be repeated.",
|
|
97
|
+
" --maxdepth: Limit heading depth (default: 6).",
|
|
98
|
+
" --no-firsth1: Include the first h1 heading.",
|
|
99
|
+
" --no-stripHeadingTags: Keep HTML tags while slugifying.",
|
|
100
|
+
" --indent: Set the indentation string (default: two spaces)."
|
|
101
|
+
].join("\n");
|
|
102
|
+
}
|
|
103
|
+
__name(usage, "usage");
|
|
104
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
105
|
+
main().catch((error) => {
|
|
106
|
+
stderr.write(`${String(error)}
|
|
107
|
+
`);
|
|
108
|
+
process.exitCode = 1;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
main
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\nimport { readFileSync, writeFileSync } from 'node:fs'\nimport { stdin, stderr, stdout } from 'node:process'\nimport { insertMarkdown, toc } from './index.js'\nimport type { TocOptions } from './types.js'\n\ntype CliArgs = TocOptions&{\n readonly _:Array<string>\n readonly i?:boolean\n readonly json?:boolean\n}\n\nexport async function main ():Promise<void> {\n const args = parseArguments(process.argv.slice(2))\n\n if (args._.length !== 1) {\n stderr.write(`${usage()}\\n`)\n process.exitCode = 1\n return\n }\n\n if (args.i && args.json) {\n stderr.write('markdown-toc: you cannot use both --json and -i\\n')\n process.exitCode = 1\n return\n }\n\n if (args.i && args._[0] === '-') {\n stderr.write(\n 'markdown-toc: you cannot use -i with \"-\" (stdin) for input\\n',\n )\n process.exitCode = 1\n return\n }\n\n const input = args._[0] === '-'\n ? await readStdin()\n : readFileSync(args._[0] ?? '', 'utf8')\n\n if (args.i) {\n const path = args._[0] ?? ''\n writeFileSync(path, insertMarkdown(input, args))\n return\n }\n\n const parsed = toc(input, args)\n if (args.json) {\n stdout.write(`${JSON.stringify(parsed.json, null, 2)}\\n`)\n } else {\n stdout.write(parsed.content)\n }\n}\n\nfunction parseArguments (argumentsList:ReadonlyArray<string>):CliArgs {\n const values:{\n _:Array<string>\n i?:boolean\n json?:boolean\n append?:string\n bullets?:Array<string>\n indent?:string\n maxdepth?:number\n firsth1?:boolean\n stripHeadingTags?:boolean\n } = {\n _:[],\n firsth1:true,\n stripHeadingTags:true,\n }\n\n for (let index = 0; index < argumentsList.length; index++) {\n const argument = argumentsList[index]\n const next = argumentsList[index + 1]\n\n if (argument === '-i') values.i = true\n else if (argument === '--json') values.json = true\n else if (argument === '--no-firsth1') values.firsth1 = false\n else if (argument === '--no-stripHeadingTags') {\n values.stripHeadingTags = false\n } else if (argument === '--append' && next) {\n values.append = next\n index++\n } else if (argument === '--bullets' && next) {\n values.bullets = [...(values.bullets ?? []), next]\n index++\n } else if (argument === '--indent' && next) {\n values.indent = next\n index++\n } else if (argument === '--maxdepth' && next) {\n values.maxdepth = Number.parseInt(next, 10)\n index++\n } else if (argument === '-') {\n values._.push(argument)\n } else if (argument?.startsWith('-')) {\n continue\n } else if (argument) {\n values._.push(argument)\n }\n }\n\n return values\n}\n\nfunction readStdin ():Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks:Array<Buffer> = []\n stdin.on('data', chunk => chunks.push(Buffer.from(chunk)))\n stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))\n stdin.on('error', reject)\n })\n}\n\nfunction usage ():string {\n return [\n 'Usage: markdown-toc [options] <input>',\n '',\n ' input: The Markdown file to parse, or \"-\" for stdin.',\n ' -i: Edit the input file and inject the TOC.',\n ' --json: Print the TOC in JSON format.',\n ' --append: Append a string to the TOC.',\n ' --bullets: Set the bullet; may be repeated.',\n ' --maxdepth: Limit heading depth (default: 6).',\n ' --no-firsth1: Include the first h1 heading.',\n ' --no-stripHeadingTags: Keep HTML tags while slugifying.',\n ' --indent: Set the indentation string (default: two spaces).',\n ].join('\\n')\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch(error => {\n stderr.write(`${String(error)}\\n`)\n process.exitCode = 1\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import Remarkable from "remarkable";
|
|
4
|
+
import {
|
|
5
|
+
generatePlugin,
|
|
6
|
+
generateToc,
|
|
7
|
+
getHighest,
|
|
8
|
+
getTitle,
|
|
9
|
+
linkify as linkifyHeading,
|
|
10
|
+
renderBullets,
|
|
11
|
+
slugify as slugifyHeading,
|
|
12
|
+
strip as stripHeading,
|
|
13
|
+
titleize as titleizeHeading
|
|
14
|
+
} from "./markdown-toc.js";
|
|
15
|
+
import { insertMarkdown } from "./insert-markdown.js";
|
|
16
|
+
function toc(markdown, options = {}) {
|
|
17
|
+
return generateToc(markdown, options);
|
|
18
|
+
}
|
|
19
|
+
__name(toc, "toc");
|
|
20
|
+
const utils = {
|
|
21
|
+
Remarkable,
|
|
22
|
+
getTitle,
|
|
23
|
+
slugify: slugifyHeading,
|
|
24
|
+
strip: stripHeading,
|
|
25
|
+
titleize: titleizeHeading
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
Remarkable,
|
|
29
|
+
renderBullets as bullets,
|
|
30
|
+
generateToc,
|
|
31
|
+
getHighest,
|
|
32
|
+
getTitle,
|
|
33
|
+
insertMarkdown,
|
|
34
|
+
linkifyHeading as linkify,
|
|
35
|
+
generatePlugin as plugin,
|
|
36
|
+
renderBullets,
|
|
37
|
+
slugifyHeading as slugify,
|
|
38
|
+
stripHeading as strip,
|
|
39
|
+
titleizeHeading as titleize,
|
|
40
|
+
toc,
|
|
41
|
+
utils
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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(markdown, 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;AAmBxB,SAAS,IACZ,UACA,UAA+B,CAAC,GACxB;AACR,SAAO,YAAY,UAAU,OAAO;AACxC;AALgB;AAOT,MAAM,QAAiB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,SAAQ;AAAA,EACR,OAAM;AAAA,EACN,UAAS;AACb;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import matter from "gray-matter";
|
|
4
|
+
import { generateToc } from "./markdown-toc.js";
|
|
5
|
+
function insertMarkdown(markdown, options = {}) {
|
|
6
|
+
const regex = options.regex ?? /(?:<!-- toc(?:\s*stop)? -->)/g;
|
|
7
|
+
const open = typeof options.open === "string" ? options.open : "<!-- toc -->\n\n";
|
|
8
|
+
const close = typeof options.close === "string" ? options.close : "<!-- tocstop -->";
|
|
9
|
+
const trailingNewlines = /\n+$/.exec(markdown)?.[0] ?? "";
|
|
10
|
+
const hasMatter = /^---/.test(markdown);
|
|
11
|
+
const parsed = hasMatter ? matter(markdown) : null;
|
|
12
|
+
const content = parsed?.content ?? markdown;
|
|
13
|
+
const sections = content.split(regex).map((section) => section.trim());
|
|
14
|
+
if (sections.length > 3) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
"markdown-toc only supports one Table of Contents per file."
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const updated = sections.slice();
|
|
20
|
+
const last = updated[updated.length - 1] ?? "";
|
|
21
|
+
const generated = options.toc ?? generateToc(last, options).content;
|
|
22
|
+
if (updated.length === 3) {
|
|
23
|
+
updated.splice(1, 1, `${open}${generated}`);
|
|
24
|
+
updated.splice(2, 0, close);
|
|
25
|
+
} else if (updated.length === 2) {
|
|
26
|
+
updated.splice(1, 0, `${open}${generated}
|
|
27
|
+
|
|
28
|
+
${close}`);
|
|
29
|
+
}
|
|
30
|
+
const result = updated.join("\n\n") + trailingNewlines;
|
|
31
|
+
return parsed ? matter.stringify(result, parsed.data) : result;
|
|
32
|
+
}
|
|
33
|
+
__name(insertMarkdown, "insertMarkdown");
|
|
34
|
+
export {
|
|
35
|
+
insertMarkdown
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=insert-markdown.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/insert-markdown.ts"],
|
|
4
|
+
"sourcesContent": ["import matter from 'gray-matter'\nimport { generateToc } from './markdown-toc.js'\nimport type { TocOptions } from './types.js'\n\nexport function insertMarkdown (\n markdown:string,\n options:Readonly<TocOptions> = {},\n):string {\n const regex = options.regex ?? /(?:<!-- toc(?:\\s*stop)? -->)/g\n const open = typeof options.open === 'string' ?\n options.open :\n '<!-- toc -->\\n\\n'\n const close = typeof options.close === 'string' ?\n options.close :\n '<!-- tocstop -->'\n const trailingNewlines = /\\n+$/.exec(markdown)?.[0] ?? ''\n const hasMatter = /^---/.test(markdown)\n const parsed = hasMatter ? matter(markdown) : null\n const content = parsed?.content ?? markdown\n const sections = content.split(regex).map(section => section.trim())\n\n if (sections.length > 3) {\n throw new Error(\n 'markdown-toc only supports one Table of Contents per file.',\n )\n }\n\n const updated = sections.slice()\n const last = updated[updated.length - 1] ?? ''\n const generated = options.toc ?? generateToc(last, options).content\n\n if (updated.length === 3) {\n updated.splice(1, 1, `${open}${generated}`)\n updated.splice(2, 0, close)\n } else if (updated.length === 2) {\n updated.splice(1, 0, `${open}${generated}\\n\\n${close}`)\n }\n\n const result = updated.join('\\n\\n') + trailingNewlines\n return parsed ? matter.stringify(result, parsed.data) : result\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,OAAO,YAAY;AACnB,SAAS,mBAAmB;AAGrB,SAAS,eACZ,UACA,UAA+B,CAAC,GAC3B;AACL,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,OAAO,OAAO,QAAQ,SAAS,WACjC,QAAQ,OACR;AACJ,QAAM,QAAQ,OAAO,QAAQ,UAAU,WACnC,QAAQ,QACR;AACJ,QAAM,mBAAmB,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK;AACvD,QAAM,YAAY,OAAO,KAAK,QAAQ;AACtC,QAAM,SAAS,YAAY,OAAO,QAAQ,IAAI;AAC9C,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,WAAW,QAAQ,MAAM,KAAK,EAAE,IAAI,aAAW,QAAQ,KAAK,CAAC;AAEnE,MAAI,SAAS,SAAS,GAAG;AACrB,UAAM,IAAI;AAAA,MACN;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,UAAU,SAAS,MAAM;AAC/B,QAAM,OAAO,QAAQ,QAAQ,SAAS,CAAC,KAAK;AAC5C,QAAM,YAAY,QAAQ,OAAO,YAAY,MAAM,OAAO,EAAE;AAE5D,MAAI,QAAQ,WAAW,GAAG;AACtB,YAAQ,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,SAAS,EAAE;AAC1C,YAAQ,OAAO,GAAG,GAAG,KAAK;AAAA,EAC9B,WAAW,QAAQ,WAAW,GAAG;AAC7B,YAAQ,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,SAAS;AAAA;AAAA,EAAO,KAAK,EAAE;AAAA,EAC1D;AAEA,QAAM,SAAS,QAAQ,KAAK,MAAM,IAAI;AACtC,SAAO,SAAS,OAAO,UAAU,QAAQ,OAAO,IAAI,IAAI;AAC5D;AApCgB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import diacritics from "diacritics-map";
|
|
4
|
+
import Remarkable from "remarkable";
|
|
5
|
+
const TOC_MARKER = /<!--[ \t]*toc[ \t]*-->/;
|
|
6
|
+
const DEFAULT_BULLETS = ["-", "*", "+"];
|
|
7
|
+
const CJK_PUNCTUATION = new RegExp(
|
|
8
|
+
"[\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u201C\u201D\u3010\u3011\uFF08\uFF09\u3014\u3015\uFF3B\uFF3D\uFE43\uFE44\u201C \u201D\u2018\u2019\uFE41\uFE42\u2014\u2026\uFF0D\uFF5E\u300A\u300B\u3008\u3009\u300C\u300D]"
|
|
9
|
+
);
|
|
10
|
+
function generateToc(markdown, options = {}) {
|
|
11
|
+
const renderer = new Remarkable().use(generatePlugin(options));
|
|
12
|
+
return renderer.render(markdown);
|
|
13
|
+
}
|
|
14
|
+
__name(generateToc, "generateToc");
|
|
15
|
+
function generatePlugin(options = {}) {
|
|
16
|
+
const configuredOptions = {
|
|
17
|
+
firsth1: true,
|
|
18
|
+
maxdepth: 6,
|
|
19
|
+
...options,
|
|
20
|
+
linkify: options.linkify ?? true
|
|
21
|
+
};
|
|
22
|
+
return /* @__PURE__ */ __name(function registerRenderer(instance) {
|
|
23
|
+
instance.renderer.render = /* @__PURE__ */ __name(function renderTokens(tokens) {
|
|
24
|
+
const tokensWithMetadata = tokens.slice();
|
|
25
|
+
const headings = [];
|
|
26
|
+
let tocStart = -1;
|
|
27
|
+
let headingIndex = 0;
|
|
28
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
29
|
+
const token = tokens[index];
|
|
30
|
+
if (token.content && TOC_MARKER.test(token.content)) {
|
|
31
|
+
tocStart = token.lines?.[1] ?? tocStart;
|
|
32
|
+
}
|
|
33
|
+
if (token.type !== "heading_open") continue;
|
|
34
|
+
const heading = tokensWithMetadata[index + 1];
|
|
35
|
+
if (!heading) continue;
|
|
36
|
+
const headingWithMetadata = {
|
|
37
|
+
...heading,
|
|
38
|
+
lvl: token.hLevel ?? 0,
|
|
39
|
+
i: headingIndex
|
|
40
|
+
};
|
|
41
|
+
tokensWithMetadata[index + 1] = headingWithMetadata;
|
|
42
|
+
headings.push(headingWithMetadata);
|
|
43
|
+
headingIndex++;
|
|
44
|
+
}
|
|
45
|
+
const seen = {};
|
|
46
|
+
const linkedHeadings = [];
|
|
47
|
+
const json = [];
|
|
48
|
+
for (const heading of headings) {
|
|
49
|
+
if (!heading.lines || heading.lines[0] <= tocStart) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const content2 = getTitle(heading.content);
|
|
53
|
+
const seenCount = seen[content2] ?? 0;
|
|
54
|
+
seen[content2] = seenCount + 1;
|
|
55
|
+
const headingOptions = {
|
|
56
|
+
...configuredOptions,
|
|
57
|
+
num: seenCount
|
|
58
|
+
};
|
|
59
|
+
const slug = slugify(content2, headingOptions);
|
|
60
|
+
const nextHeading = {
|
|
61
|
+
...heading,
|
|
62
|
+
content: content2,
|
|
63
|
+
seen: seenCount,
|
|
64
|
+
slug
|
|
65
|
+
};
|
|
66
|
+
json.push({
|
|
67
|
+
content: content2,
|
|
68
|
+
slug,
|
|
69
|
+
lvl: nextHeading.lvl ?? 0,
|
|
70
|
+
i: nextHeading.i ?? 0,
|
|
71
|
+
seen: seenCount
|
|
72
|
+
});
|
|
73
|
+
linkedHeadings.push(
|
|
74
|
+
configuredOptions.linkify ? linkify(nextHeading, headingOptions) : nextHeading
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
const highest = getHighest(linkedHeadings);
|
|
78
|
+
const headingsForOutput = configuredOptions.firsth1 === false ? linkedHeadings.slice(1) : linkedHeadings;
|
|
79
|
+
const content = renderBullets(headingsForOutput, {
|
|
80
|
+
...configuredOptions,
|
|
81
|
+
highest
|
|
82
|
+
}) + (configuredOptions.append ?? "");
|
|
83
|
+
const linkedByIndex = {};
|
|
84
|
+
for (const heading of linkedHeadings) {
|
|
85
|
+
if (heading.i !== void 0) {
|
|
86
|
+
linkedByIndex[heading.i] = heading;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const outputTokens = tokensWithMetadata.map((token) => {
|
|
90
|
+
if (token.i === void 0) return token;
|
|
91
|
+
return linkedByIndex[token.i] ?? token;
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
content,
|
|
95
|
+
highest,
|
|
96
|
+
json,
|
|
97
|
+
tokens: outputTokens
|
|
98
|
+
};
|
|
99
|
+
}, "renderTokens");
|
|
100
|
+
}, "registerRenderer");
|
|
101
|
+
}
|
|
102
|
+
__name(generatePlugin, "generatePlugin");
|
|
103
|
+
function renderBullets(tokens, options = {}) {
|
|
104
|
+
const indent = options.indent ?? " ";
|
|
105
|
+
const bullets = getBullets(options);
|
|
106
|
+
const highest = options.highest ?? getHighest(tokens);
|
|
107
|
+
const unindent = options.firsth1 === false ? 1 : 0;
|
|
108
|
+
const filter = options.filter;
|
|
109
|
+
const result = [];
|
|
110
|
+
for (const token of tokens) {
|
|
111
|
+
const level = (token.lvl ?? 0) - unindent;
|
|
112
|
+
const adjusted = { ...token, lvl: level };
|
|
113
|
+
if (filter && !filter(adjusted.content, adjusted, tokens)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (level > (options.maxdepth ?? 6)) continue;
|
|
117
|
+
const relativeLevel = level - highest;
|
|
118
|
+
result.push(renderListItem(
|
|
119
|
+
relativeLevel,
|
|
120
|
+
adjusted.content,
|
|
121
|
+
bullets,
|
|
122
|
+
indent
|
|
123
|
+
));
|
|
124
|
+
}
|
|
125
|
+
return result.join("\n");
|
|
126
|
+
}
|
|
127
|
+
__name(renderBullets, "renderBullets");
|
|
128
|
+
function linkify(token, options = {}) {
|
|
129
|
+
if (!token || !token.content) return token ?? emptyToken();
|
|
130
|
+
const headingOptions = { ...options, num: token.seen };
|
|
131
|
+
const text = titleize(token.content, headingOptions);
|
|
132
|
+
const slug = encodeURIComponent(slugify(token.content, headingOptions));
|
|
133
|
+
const customLinkify = options.linkify;
|
|
134
|
+
if (typeof customLinkify === "function") {
|
|
135
|
+
return customLinkify(token, text, slug, headingOptions);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
...token,
|
|
139
|
+
content: `[${text}](#${slug})`
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
__name(linkify, "linkify");
|
|
143
|
+
function slugify(text, options = {}) {
|
|
144
|
+
if (options.slugify === false) return text;
|
|
145
|
+
if (typeof options.slugify === "function") {
|
|
146
|
+
return options.slugify(text, options);
|
|
147
|
+
}
|
|
148
|
+
let slug = getTitle(text);
|
|
149
|
+
slug = stripColor(slug).toLowerCase();
|
|
150
|
+
slug = slug.split(" ").join("-");
|
|
151
|
+
slug = slug.split(/\t/).join("--");
|
|
152
|
+
if (options.stripHeadingTags !== false) {
|
|
153
|
+
slug = slug.split(/<\/?[^>]+>/).join("");
|
|
154
|
+
}
|
|
155
|
+
slug = slug.split(/[|$&`~=\\\u002f@+*!?({[\]})<>=.,;:'"^]/).join("");
|
|
156
|
+
slug = slug.split(CJK_PUNCTUATION).join("");
|
|
157
|
+
slug = replaceDiacritics(slug);
|
|
158
|
+
if (options.num) slug += `-${options.num}`;
|
|
159
|
+
return slug;
|
|
160
|
+
}
|
|
161
|
+
__name(slugify, "slugify");
|
|
162
|
+
function titleize(text, options = {}) {
|
|
163
|
+
if (options.strip) return strip(text, options);
|
|
164
|
+
if (options.titleize === false) return text;
|
|
165
|
+
if (typeof options.titleize === "function") {
|
|
166
|
+
return options.titleize(text, options);
|
|
167
|
+
}
|
|
168
|
+
return getTitle(text).split(/<\/?[^>]+>/).join("").split(/[ \t]+/).join(" ").trim();
|
|
169
|
+
}
|
|
170
|
+
__name(titleize, "titleize");
|
|
171
|
+
function strip(text, options = {}) {
|
|
172
|
+
const words = options.strip;
|
|
173
|
+
if (!words) return text;
|
|
174
|
+
if (typeof words === "function") return words(text, options);
|
|
175
|
+
if (!words.length) return text;
|
|
176
|
+
const expression = new RegExp(words.join("|"), "g");
|
|
177
|
+
return text.trim().replace(expression, "").replace(/^-|-$/g, "");
|
|
178
|
+
}
|
|
179
|
+
__name(strip, "strip");
|
|
180
|
+
function getTitle(text) {
|
|
181
|
+
const match = /^\[[^\]]+\]\(/.test(text) ? /^\[([^\]]+)\]/.exec(text) : null;
|
|
182
|
+
return match?.[1] ?? text;
|
|
183
|
+
}
|
|
184
|
+
__name(getTitle, "getTitle");
|
|
185
|
+
function getHighest(tokens) {
|
|
186
|
+
if (!tokens.length) return 0;
|
|
187
|
+
return tokens.reduce((highest, token) => {
|
|
188
|
+
const level = token.lvl ?? 0;
|
|
189
|
+
return level < highest ? level : highest;
|
|
190
|
+
}, Number.POSITIVE_INFINITY);
|
|
191
|
+
}
|
|
192
|
+
__name(getHighest, "getHighest");
|
|
193
|
+
function getBullets(options) {
|
|
194
|
+
const configured = options.chars ?? options.bullets;
|
|
195
|
+
if (typeof configured === "string") return [configured];
|
|
196
|
+
return configured?.length ? configured : DEFAULT_BULLETS;
|
|
197
|
+
}
|
|
198
|
+
__name(getBullets, "getBullets");
|
|
199
|
+
function renderListItem(level, content, bullets, indent) {
|
|
200
|
+
const safeLevel = Math.max(0, level);
|
|
201
|
+
const bullet = bullets[safeLevel % bullets.length] ?? "-";
|
|
202
|
+
return `${indent.repeat(safeLevel)}${bullet} ${content}`;
|
|
203
|
+
}
|
|
204
|
+
__name(renderListItem, "renderListItem");
|
|
205
|
+
function replaceDiacritics(text) {
|
|
206
|
+
return text.replace(/[À-ž]/g, (character) => {
|
|
207
|
+
return diacritics[character] ?? character;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
__name(replaceDiacritics, "replaceDiacritics");
|
|
211
|
+
function stripColor(text) {
|
|
212
|
+
return text.replace(/\x1B[[(?);]{0,2}(;?\d)*./g, "");
|
|
213
|
+
}
|
|
214
|
+
__name(stripColor, "stripColor");
|
|
215
|
+
function emptyToken() {
|
|
216
|
+
return { type: "", content: "" };
|
|
217
|
+
}
|
|
218
|
+
__name(emptyToken, "emptyToken");
|
|
219
|
+
export {
|
|
220
|
+
generatePlugin,
|
|
221
|
+
generateToc,
|
|
222
|
+
getHighest,
|
|
223
|
+
getTitle,
|
|
224
|
+
linkify,
|
|
225
|
+
renderBullets,
|
|
226
|
+
slugify,
|
|
227
|
+
strip,
|
|
228
|
+
titleize
|
|
229
|
+
};
|
|
230
|
+
//# sourceMappingURL=markdown-toc.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/markdown-toc.ts"],
|
|
4
|
+
"sourcesContent": ["import diacritics from 'diacritics-map'\nimport Remarkable from 'remarkable'\nimport type {\n RemarkablePlugin,\n TocHeading,\n TocOptions,\n TocResult,\n TocToken,\n} from './types.js'\n\nconst TOC_MARKER = /<!--[ \\t]*toc[ \\t]*-->/\nconst DEFAULT_BULLETS = ['-', '*', '+']\nconst CJK_PUNCTUATION = new RegExp(\n '[\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u201C\u201D\u3010\u3011\uFF08\uFF09' +\n '\u3014\u3015\uFF3B\uFF3D\uFE43\uFE44\u201C \u201D\u2018\u2019\uFE41\uFE42\u2014\u2026\uFF0D\uFF5E\u300A\u300B\u3008\u3009\u300C\u300D]',\n)\n\nexport function generateToc (\n markdown:string,\n options:Readonly<TocOptions> = {},\n):TocResult {\n const renderer = new Remarkable()\n .use(generatePlugin(options))\n\n return renderer.render(markdown) as TocResult\n}\n\nexport function generatePlugin (\n options:Readonly<TocOptions> = {},\n):RemarkablePlugin {\n const configuredOptions:TocOptions = {\n firsth1:true,\n maxdepth:6,\n ...options,\n linkify:options.linkify ?? true,\n }\n\n return function registerRenderer (instance):void {\n instance.renderer.render = function renderTokens (\n tokens:Array<TocToken>,\n ):TocResult {\n const tokensWithMetadata = tokens.slice()\n const headings:Array<TocToken> = []\n let tocStart = -1\n let headingIndex = 0\n\n for (let index = 0; index < tokens.length; index++) {\n const token = tokens[index]\n\n if (token.content && TOC_MARKER.test(token.content)) {\n tocStart = token.lines?.[1] ?? tocStart\n }\n\n if (token.type !== 'heading_open') continue\n\n const heading = tokensWithMetadata[index + 1]\n if (!heading) continue\n\n const headingWithMetadata = {\n ...heading,\n lvl:token.hLevel ?? 0,\n i:headingIndex,\n }\n tokensWithMetadata[index + 1] = headingWithMetadata\n headings.push(headingWithMetadata)\n headingIndex++\n }\n\n const seen:Record<string, number> = {}\n const linkedHeadings:Array<TocToken> = []\n const json:Array<TocHeading> = []\n\n for (const heading of headings) {\n if (!heading.lines || heading.lines[0] <= tocStart) {\n continue\n }\n\n const content = getTitle(heading.content)\n const seenCount = seen[content] ?? 0\n seen[content] = seenCount + 1\n const headingOptions = {\n ...configuredOptions,\n num:seenCount,\n }\n const slug = slugify(content, headingOptions)\n const nextHeading:TocToken = {\n ...heading,\n content,\n seen:seenCount,\n slug,\n }\n\n json.push({\n content,\n slug,\n lvl:nextHeading.lvl ?? 0,\n i:nextHeading.i ?? 0,\n seen:seenCount,\n })\n linkedHeadings.push(\n configuredOptions.linkify\n ? linkify(nextHeading, headingOptions)\n : nextHeading,\n )\n }\n\n const highest = getHighest(linkedHeadings)\n const headingsForOutput = configuredOptions.firsth1 === false\n ? linkedHeadings.slice(1)\n : linkedHeadings\n const content = renderBullets(headingsForOutput, {\n ...configuredOptions,\n highest,\n }) + (configuredOptions.append ?? '')\n const linkedByIndex:Record<number, TocToken> = {}\n\n for (const heading of linkedHeadings) {\n if (heading.i !== undefined) {\n linkedByIndex[heading.i] = heading\n }\n }\n const outputTokens = tokensWithMetadata.map(token => {\n if (token.i === undefined) return token\n return linkedByIndex[token.i] ?? token\n })\n\n return {\n content,\n highest,\n json,\n tokens:outputTokens,\n }\n }\n }\n}\n\nexport function renderBullets (\n tokens:ReadonlyArray<TocToken>,\n options:Readonly<TocOptions> = {},\n):string {\n const indent = options.indent ?? ' '\n const bullets = getBullets(options)\n const highest = options.highest ?? getHighest(tokens)\n const unindent = options.firsth1 === false ? 1 : 0\n const filter = options.filter\n const result:Array<string> = []\n\n for (const token of tokens) {\n const level = (token.lvl ?? 0) - unindent\n const adjusted = { ...token, lvl:level }\n\n if (filter && !filter(adjusted.content, adjusted, tokens)) {\n continue\n }\n\n if (level > (options.maxdepth ?? 6)) continue\n\n const relativeLevel = level - highest\n result.push(renderListItem(\n relativeLevel,\n adjusted.content,\n bullets,\n indent,\n ))\n }\n\n return result.join('\\n')\n}\n\nexport function linkify (\n token:TocToken|null,\n options:Readonly<TocOptions> = {},\n):TocToken {\n if (!token || !token.content) return token ?? emptyToken()\n\n const headingOptions = { ...options, num:token.seen }\n const text = titleize(token.content, headingOptions)\n const slug = encodeURIComponent(slugify(token.content, headingOptions))\n const customLinkify = options.linkify\n\n if (typeof customLinkify === 'function') {\n return customLinkify(token, text, slug, headingOptions)\n }\n\n return {\n ...token,\n content:`[${text}](#${slug})`,\n }\n}\n\nexport function slugify (\n text:string,\n options:Readonly<TocOptions> = {},\n):string {\n if (options.slugify === false) return text\n if (typeof options.slugify === 'function') {\n return options.slugify(text, options)\n }\n\n let slug = getTitle(text)\n slug = stripColor(slug).toLowerCase()\n slug = slug.split(' ').join('-')\n slug = slug.split(/\\t/).join('--')\n\n if (options.stripHeadingTags !== false) {\n slug = slug.split(/<\\/?[^>]+>/).join('')\n }\n\n slug = slug.split(/[|$&`~=\\\\\\u002f@+*!?({[\\]})<>=.,;:'\"^]/).join('')\n slug = slug.split(CJK_PUNCTUATION).join('')\n slug = replaceDiacritics(slug)\n\n if (options.num) slug += `-${options.num}`\n return slug\n}\n\nexport function titleize (\n text:string,\n options:Readonly<TocOptions> = {},\n):string {\n if (options.strip) return strip(text, options)\n if (options.titleize === false) return text\n if (typeof options.titleize === 'function') {\n return options.titleize(text, options)\n }\n\n return getTitle(text)\n .split(/<\\/?[^>]+>/).join('')\n .split(/[ \\t]+/).join(' ')\n .trim()\n}\n\nexport function strip (\n text:string,\n options:Readonly<TocOptions> = {},\n):string {\n const words = options.strip\n if (!words) return text\n if (typeof words === 'function') return words(text, options)\n if (!words.length) return text\n\n const expression = new RegExp(words.join('|'), 'g')\n return text.trim().replace(expression, '').replace(/^-|-$/g, '')\n}\n\nexport function getTitle (text:string):string {\n const match = /^\\[[^\\]]+\\]\\(/.test(text)\n ? /^\\[([^\\]]+)\\]/.exec(text)\n : null\n\n return match?.[1] ?? text\n}\n\nexport function getHighest (tokens:ReadonlyArray<TocToken>):number {\n if (!tokens.length) return 0\n\n return tokens.reduce((highest, token) => {\n const level = token.lvl ?? 0\n return level < highest ? level : highest\n }, Number.POSITIVE_INFINITY)\n}\n\nfunction getBullets (options:Readonly<TocOptions>):ReadonlyArray<string> {\n const configured = options.chars ?? options.bullets\n if (typeof configured === 'string') return [configured]\n return configured?.length ? configured : DEFAULT_BULLETS\n}\n\nfunction renderListItem (\n level:number,\n content:string,\n bullets:ReadonlyArray<string>,\n indent:string,\n):string {\n const safeLevel = Math.max(0, level)\n const bullet = bullets[safeLevel % bullets.length] ?? '-'\n return `${indent.repeat(safeLevel)}${bullet} ${content}`\n}\n\nfunction replaceDiacritics (text:string):string {\n return text.replace(/[\u00C0-\u017E]/g, character => {\n return diacritics[character] ?? character\n })\n}\n\nfunction stripColor (text:string):string {\n /* eslint-disable-next-line */\n return text.replace(/\\x1B[[(?);]{0,2}(;?\\d)*./g, '')\n}\n\nfunction emptyToken ():TocToken {\n return { type:'', content:'' }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["content"]
|
|
7
|
+
}
|