better sidebar

Signed-off-by: taskylizard <75871323+taskylizard@users.noreply.github.com>
This commit is contained in:
taskylizard 2023-07-30 16:23:39 +02:00
parent 1fe1233cc9
commit db5ea0a95e
6 changed files with 800 additions and 9 deletions

View File

@ -2,17 +2,22 @@ import fs from "fs";
import path from "path";
import matter, { type GrayMatterFile } from "gray-matter";
import { buildTOC } from "./toc";
import { getTableOfContents, Items } from "../shared";
const dir = path.join(__dirname, "/wiki/");
function getMetadata(path: string): GrayMatterFile<string> {
async function getMetadata(
path: string,
): Promise<{ frontmatter: GrayMatterFile<string>; toc: Items }> {
const contents = fs.readFileSync(path, "utf8");
return matter(contents);
const frontmatter = matter(contents);
const toc = await getTableOfContents(contents);
return { frontmatter, toc };
}
export function generateSidebar(locale: string): any[] {
let localePath = "";
let items: { text: string; link: string }[] = [];
let items: { text: string; items: { text: string; link: string }[] }[] = [];
buildTOC();
@ -22,17 +27,20 @@ export function generateSidebar(locale: string): any[] {
localePath = `${dir}`;
}
fs.readdirSync(localePath).forEach((file) => {
fs.readdirSync(localePath).forEach(async (file) => {
const filePath = path.join(localePath, file);
const stat = fs.statSync(filePath);
if (stat.isFile() && path.extname(file) === ".md") {
const title = getMetadata(filePath).data.title;
const { frontmatter, toc } = await getMetadata(filePath);
const title = frontmatter.data.title;
if (!title) throw new Error("Cannot find title in metadata: " + filePath);
const tocItems = toc.items?.map((item) => ({
text: item.title,
link: `/wiki/${file.replace(/\.md$/, "")}${item.url}`,
}));
items.push({
text: title,
link: `/wiki/${file.replace(/\.md$/, "")}`,
items: tocItems!,
});
}
});

View File

@ -1,6 +1,7 @@
---
editLink: false
---
# Get Started
<!--@include: ./toc.md -->

View File

@ -1,6 +1,7 @@
{
"name": "wiki",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"scripts": {
"format": "prettier --log-level=warn --write .",
@ -23,6 +24,9 @@
}
},
"dependencies": {
"gray-matter": "^4.0.3"
"gray-matter": "^4.0.3",
"mdast-util-toc": "^7.0.0",
"remark": "^14.0.3",
"unist-util-visit": "^5.0.0"
}
}

View File

@ -8,6 +8,15 @@ dependencies:
gray-matter:
specifier: ^4.0.3
version: 4.0.3
mdast-util-toc:
specifier: ^7.0.0
version: 7.0.0
remark:
specifier: ^14.0.3
version: 14.0.3
unist-util-visit:
specifier: ^5.0.0
version: 5.0.0
devDependencies:
"@types/node":
@ -572,6 +581,40 @@ packages:
}
dev: true
/@types/debug@4.1.8:
resolution:
{
integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==,
}
dependencies:
"@types/ms": 0.7.31
dev: false
/@types/mdast@3.0.12:
resolution:
{
integrity: sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==,
}
dependencies:
"@types/unist": 2.0.7
dev: false
/@types/mdast@4.0.0:
resolution:
{
integrity: sha512-YLeG8CujC9adtj/kuDzq1N4tCDYKoZ5l/bnjq8d74+t/3q/tHquJOJKUQXJrLCflOHpKjXgcI/a929gpmLOEng==,
}
dependencies:
"@types/unist": 3.0.0
dev: false
/@types/ms@0.7.31:
resolution:
{
integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==,
}
dev: false
/@types/node@20.4.5:
resolution:
{
@ -579,6 +622,27 @@ packages:
}
dev: true
/@types/ungap__structured-clone@0.3.0:
resolution:
{
integrity: sha512-eBWREUhVUGPze+bUW22AgUr05k8u+vETzuYdLYSvWqGTUe0KOf+zVnOB1qER5wMcw8V6D9Ar4DfJmVvD1yu0kQ==,
}
dev: false
/@types/unist@2.0.7:
resolution:
{
integrity: sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==,
}
dev: false
/@types/unist@3.0.0:
resolution:
{
integrity: sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==,
}
dev: false
/@types/web-bluetooth@0.0.17:
resolution:
{
@ -586,6 +650,13 @@ packages:
}
dev: true
/@ungap/structured-clone@1.2.0:
resolution:
{
integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==,
}
dev: false
/@vitejs/plugin-vue@4.2.3(vite@4.4.7)(vue@3.3.4):
resolution:
{
@ -845,6 +916,13 @@ packages:
sprintf-js: 1.0.3
dev: false
/bail@2.0.2:
resolution:
{
integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==,
}
dev: false
/body-scroll-lock@4.0.0-beta.0:
resolution:
{
@ -852,6 +930,13 @@ packages:
}
dev: true
/character-entities@2.0.2:
resolution:
{
integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==,
}
dev: false
/csstype@3.1.2:
resolution:
{
@ -859,6 +944,46 @@ packages:
}
dev: true
/debug@4.3.4:
resolution:
{
integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==,
}
engines: { node: ">=6.0" }
peerDependencies:
supports-color: "*"
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: false
/decode-named-character-reference@1.0.2:
resolution:
{
integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==,
}
dependencies:
character-entities: 2.0.2
dev: false
/dequal@2.0.3:
resolution:
{
integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==,
}
engines: { node: ">=6" }
dev: false
/diff@5.1.0:
resolution:
{
integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==,
}
engines: { node: ">=0.3.1" }
dev: false
/esbuild@0.18.17:
resolution:
{
@ -918,6 +1043,13 @@ packages:
is-extendable: 0.1.1
dev: false
/extend@3.0.2:
resolution:
{
integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==,
}
dev: false
/focus-trap@7.5.2:
resolution:
{
@ -938,6 +1070,13 @@ packages:
dev: true
optional: true
/github-slugger@2.0.0:
resolution:
{
integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==,
}
dev: false
/gray-matter@4.0.3:
resolution:
{
@ -951,6 +1090,14 @@ packages:
strip-bom-string: 1.0.0
dev: false
/is-buffer@2.0.5:
resolution:
{
integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==,
}
engines: { node: ">=4" }
dev: false
/is-extendable@0.1.1:
resolution:
{
@ -959,6 +1106,14 @@ packages:
engines: { node: ">=0.10.0" }
dev: false
/is-plain-obj@4.1.0:
resolution:
{
integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==,
}
engines: { node: ">=12" }
dev: false
/js-yaml@3.14.1:
resolution:
{
@ -985,6 +1140,21 @@ packages:
engines: { node: ">=0.10.0" }
dev: false
/kleur@4.1.5:
resolution:
{
integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==,
}
engines: { node: ">=6" }
dev: false
/longest-streak@3.1.0:
resolution:
{
integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==,
}
dev: false
/magic-string@0.30.2:
resolution:
{
@ -1002,6 +1172,325 @@ packages:
}
dev: true
/mdast-util-from-markdown@1.3.1:
resolution:
{
integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==,
}
dependencies:
"@types/mdast": 3.0.12
"@types/unist": 2.0.7
decode-named-character-reference: 1.0.2
mdast-util-to-string: 3.2.0
micromark: 3.2.0
micromark-util-decode-numeric-character-reference: 1.1.0
micromark-util-decode-string: 1.1.0
micromark-util-normalize-identifier: 1.1.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
unist-util-stringify-position: 3.0.3
uvu: 0.5.6
transitivePeerDependencies:
- supports-color
dev: false
/mdast-util-phrasing@3.0.1:
resolution:
{
integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==,
}
dependencies:
"@types/mdast": 3.0.12
unist-util-is: 5.2.1
dev: false
/mdast-util-to-markdown@1.5.0:
resolution:
{
integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==,
}
dependencies:
"@types/mdast": 3.0.12
"@types/unist": 2.0.7
longest-streak: 3.1.0
mdast-util-phrasing: 3.0.1
mdast-util-to-string: 3.2.0
micromark-util-decode-string: 1.1.0
unist-util-visit: 4.1.2
zwitch: 2.0.4
dev: false
/mdast-util-to-string@3.2.0:
resolution:
{
integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==,
}
dependencies:
"@types/mdast": 3.0.12
dev: false
/mdast-util-to-string@4.0.0:
resolution:
{
integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==,
}
dependencies:
"@types/mdast": 4.0.0
dev: false
/mdast-util-toc@7.0.0:
resolution:
{
integrity: sha512-C28UcSqjmnWuvgT8d97qpaItHKvySqVPAECUzqQ51xuMyNFFJwcFoKW77KoMjtXrclTidLQFDzLUmTmrshRweA==,
}
dependencies:
"@types/mdast": 4.0.0
"@types/ungap__structured-clone": 0.3.0
"@ungap/structured-clone": 1.2.0
github-slugger: 2.0.0
mdast-util-to-string: 4.0.0
unist-util-is: 6.0.0
unist-util-visit: 5.0.0
dev: false
/micromark-core-commonmark@1.1.0:
resolution:
{
integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==,
}
dependencies:
decode-named-character-reference: 1.0.2
micromark-factory-destination: 1.1.0
micromark-factory-label: 1.1.0
micromark-factory-space: 1.1.0
micromark-factory-title: 1.1.0
micromark-factory-whitespace: 1.1.0
micromark-util-character: 1.2.0
micromark-util-chunked: 1.1.0
micromark-util-classify-character: 1.1.0
micromark-util-html-tag-name: 1.2.0
micromark-util-normalize-identifier: 1.1.0
micromark-util-resolve-all: 1.1.0
micromark-util-subtokenize: 1.1.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
uvu: 0.5.6
dev: false
/micromark-factory-destination@1.1.0:
resolution:
{
integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==,
}
dependencies:
micromark-util-character: 1.2.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
dev: false
/micromark-factory-label@1.1.0:
resolution:
{
integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==,
}
dependencies:
micromark-util-character: 1.2.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
uvu: 0.5.6
dev: false
/micromark-factory-space@1.1.0:
resolution:
{
integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==,
}
dependencies:
micromark-util-character: 1.2.0
micromark-util-types: 1.1.0
dev: false
/micromark-factory-title@1.1.0:
resolution:
{
integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==,
}
dependencies:
micromark-factory-space: 1.1.0
micromark-util-character: 1.2.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
dev: false
/micromark-factory-whitespace@1.1.0:
resolution:
{
integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==,
}
dependencies:
micromark-factory-space: 1.1.0
micromark-util-character: 1.2.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
dev: false
/micromark-util-character@1.2.0:
resolution:
{
integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==,
}
dependencies:
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
dev: false
/micromark-util-chunked@1.1.0:
resolution:
{
integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==,
}
dependencies:
micromark-util-symbol: 1.1.0
dev: false
/micromark-util-classify-character@1.1.0:
resolution:
{
integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==,
}
dependencies:
micromark-util-character: 1.2.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
dev: false
/micromark-util-combine-extensions@1.1.0:
resolution:
{
integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==,
}
dependencies:
micromark-util-chunked: 1.1.0
micromark-util-types: 1.1.0
dev: false
/micromark-util-decode-numeric-character-reference@1.1.0:
resolution:
{
integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==,
}
dependencies:
micromark-util-symbol: 1.1.0
dev: false
/micromark-util-decode-string@1.1.0:
resolution:
{
integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==,
}
dependencies:
decode-named-character-reference: 1.0.2
micromark-util-character: 1.2.0
micromark-util-decode-numeric-character-reference: 1.1.0
micromark-util-symbol: 1.1.0
dev: false
/micromark-util-encode@1.1.0:
resolution:
{
integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==,
}
dev: false
/micromark-util-html-tag-name@1.2.0:
resolution:
{
integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==,
}
dev: false
/micromark-util-normalize-identifier@1.1.0:
resolution:
{
integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==,
}
dependencies:
micromark-util-symbol: 1.1.0
dev: false
/micromark-util-resolve-all@1.1.0:
resolution:
{
integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==,
}
dependencies:
micromark-util-types: 1.1.0
dev: false
/micromark-util-sanitize-uri@1.2.0:
resolution:
{
integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==,
}
dependencies:
micromark-util-character: 1.2.0
micromark-util-encode: 1.1.0
micromark-util-symbol: 1.1.0
dev: false
/micromark-util-subtokenize@1.1.0:
resolution:
{
integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==,
}
dependencies:
micromark-util-chunked: 1.1.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
uvu: 0.5.6
dev: false
/micromark-util-symbol@1.1.0:
resolution:
{
integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==,
}
dev: false
/micromark-util-types@1.1.0:
resolution:
{
integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==,
}
dev: false
/micromark@3.2.0:
resolution:
{
integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==,
}
dependencies:
"@types/debug": 4.1.8
debug: 4.3.4
decode-named-character-reference: 1.0.2
micromark-core-commonmark: 1.1.0
micromark-factory-space: 1.1.0
micromark-util-character: 1.2.0
micromark-util-chunked: 1.1.0
micromark-util-combine-extensions: 1.1.0
micromark-util-decode-numeric-character-reference: 1.1.0
micromark-util-encode: 1.1.0
micromark-util-normalize-identifier: 1.1.0
micromark-util-resolve-all: 1.1.0
micromark-util-sanitize-uri: 1.2.0
micromark-util-subtokenize: 1.1.0
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
uvu: 0.5.6
transitivePeerDependencies:
- supports-color
dev: false
/minisearch@6.1.0:
resolution:
{
@ -1009,6 +1498,21 @@ packages:
}
dev: true
/mri@1.2.0:
resolution:
{
integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==,
}
engines: { node: ">=4" }
dev: false
/ms@2.1.2:
resolution:
{
integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==,
}
dev: false
/nanoid@3.3.6:
resolution:
{
@ -1053,6 +1557,44 @@ packages:
hasBin: true
dev: true
/remark-parse@10.0.2:
resolution:
{
integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==,
}
dependencies:
"@types/mdast": 3.0.12
mdast-util-from-markdown: 1.3.1
unified: 10.1.2
transitivePeerDependencies:
- supports-color
dev: false
/remark-stringify@10.0.3:
resolution:
{
integrity: sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==,
}
dependencies:
"@types/mdast": 3.0.12
mdast-util-to-markdown: 1.5.0
unified: 10.1.2
dev: false
/remark@14.0.3:
resolution:
{
integrity: sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==,
}
dependencies:
"@types/mdast": 3.0.12
remark-parse: 10.0.2
remark-stringify: 10.0.3
unified: 10.1.2
transitivePeerDependencies:
- supports-color
dev: false
/rollup@3.27.0:
resolution:
{
@ -1064,6 +1606,16 @@ packages:
fsevents: 2.3.2
dev: true
/sade@1.8.1:
resolution:
{
integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==,
}
engines: { node: ">=6" }
dependencies:
mri: 1.2.0
dev: false
/search-insights@2.7.0:
resolution:
{
@ -1133,6 +1685,133 @@ packages:
engines: { node: ">=4" }
dev: true
/trough@2.1.0:
resolution:
{
integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==,
}
dev: false
/unified@10.1.2:
resolution:
{
integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==,
}
dependencies:
"@types/unist": 2.0.7
bail: 2.0.2
extend: 3.0.2
is-buffer: 2.0.5
is-plain-obj: 4.1.0
trough: 2.1.0
vfile: 5.3.7
dev: false
/unist-util-is@5.2.1:
resolution:
{
integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==,
}
dependencies:
"@types/unist": 2.0.7
dev: false
/unist-util-is@6.0.0:
resolution:
{
integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==,
}
dependencies:
"@types/unist": 3.0.0
dev: false
/unist-util-stringify-position@3.0.3:
resolution:
{
integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==,
}
dependencies:
"@types/unist": 2.0.7
dev: false
/unist-util-visit-parents@5.1.3:
resolution:
{
integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==,
}
dependencies:
"@types/unist": 2.0.7
unist-util-is: 5.2.1
dev: false
/unist-util-visit-parents@6.0.1:
resolution:
{
integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==,
}
dependencies:
"@types/unist": 3.0.0
unist-util-is: 6.0.0
dev: false
/unist-util-visit@4.1.2:
resolution:
{
integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==,
}
dependencies:
"@types/unist": 2.0.7
unist-util-is: 5.2.1
unist-util-visit-parents: 5.1.3
dev: false
/unist-util-visit@5.0.0:
resolution:
{
integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==,
}
dependencies:
"@types/unist": 3.0.0
unist-util-is: 6.0.0
unist-util-visit-parents: 6.0.1
dev: false
/uvu@0.5.6:
resolution:
{
integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==,
}
engines: { node: ">=8" }
hasBin: true
dependencies:
dequal: 2.0.3
diff: 5.1.0
kleur: 4.1.5
sade: 1.8.1
dev: false
/vfile-message@3.1.4:
resolution:
{
integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==,
}
dependencies:
"@types/unist": 2.0.7
unist-util-stringify-position: 3.0.3
dev: false
/vfile@5.3.7:
resolution:
{
integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==,
}
dependencies:
"@types/unist": 2.0.7
is-buffer: 2.0.5
unist-util-stringify-position: 3.0.3
vfile-message: 3.1.4
dev: false
/vite@4.4.7(@types/node@20.4.5):
resolution:
{
@ -1263,3 +1942,10 @@ packages:
"@vue/server-renderer": 3.3.4(vue@3.3.4)
"@vue/shared": 3.3.4
dev: true
/zwitch@2.0.4:
resolution:
{
integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==,
}
dev: false

78
shared.ts Normal file
View File

@ -0,0 +1,78 @@
// @ts-nocheck
import { toc } from "mdast-util-toc";
import { remark } from "remark";
import { visit } from "unist-util-visit";
const textTypes = ["text", "emphasis", "strong", "inlineCode"];
function flattenNode(node) {
const p = [];
visit(node, (node) => {
if (!textTypes.includes(node.type)) return;
p.push(node.value);
});
return p.join(``);
}
interface Item {
title: string;
url: string;
items?: Item[];
}
export interface Items {
items?: Item[];
}
function getItems(node, current): Items {
if (!node) {
return {};
}
if (node.type === "paragraph") {
visit(node, (item) => {
if (item.type === "link") {
current.url = item.url;
current.title = flattenNode(node);
}
if (item.type === "text") {
current.title = flattenNode(node);
}
});
return current;
}
if (node.type === "list") {
current.items = node.children.map((i) => getItems(i, {}));
return current;
} else if (node.type === "listItem") {
const heading = getItems(node.children[0], {});
if (node.children.length > 1) {
getItems(node.children[1], heading);
}
return heading;
}
return {};
}
const getToc = () => (node, file) => {
const table = toc(node);
file.data = getItems(table.map, {});
};
export type TableOfContents = Items;
export async function getTableOfContents(
content: string,
): Promise<TableOfContents> {
const result = await remark().use(getToc).process(content);
return result.data;
}

14
test.ts Normal file
View File

@ -0,0 +1,14 @@
import fs from "fs";
import path from "path";
import { getTableOfContents } from "./shared";
function saveFile() {
return new Promise((rslv, rjct) => {
getTableOfContents(
fs.readFileSync("./docs/wiki/emulation.md", "utf8"),
).then((foo) => {
console.log(JSON.stringify(foo, null, 2));
});
});
}
saveFile();