From 3ee57e63cedcd0445f6a4f097310e540b7fd23f2 Mon Sep 17 00:00:00 2001 From: Luma Date: Mon, 12 Feb 2024 20:08:58 +0900 Subject: [PATCH] =?UTF-8?q?minor:=20LumaToc=E3=82=92=E6=AE=8B=E3=81=99?= =?UTF-8?q?=E6=96=B9=E9=87=9D=E3=81=AE=E5=BB=83=E6=AD=A2=EF=BC=8Chast-to-e?= =?UTF-8?q?stree=E3=81=97=E3=81=A6=E9=85=8D=E5=88=97=E3=81=A8=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=83=97=E3=83=AD=E3=83=91=E3=83=86=E3=82=A3=E3=81=8B?= =?UTF-8?q?=E3=82=89=E6=B8=A1=E3=81=99=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=EF=BC=8E=E3=81=9D=E3=81=86=E3=81=97=E3=81=AA=E3=81=84?= =?UTF-8?q?=E3=81=A8Next.js=E7=AD=89=E3=81=AERSC=E3=81=AB=E3=81=A6?= =?UTF-8?q?=E7=89=B9=E5=88=A5=E3=81=AA=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=82=AF=E3=83=88=E3=81=AB=E7=BD=AE=E3=81=8D=E6=8F=9B=E3=82=8F?= =?UTF-8?q?=E3=81=A3=E3=81=A6=E3=81=84=E3=82=8B=E9=9A=9B=E3=81=AB=E5=9E=8B?= =?UTF-8?q?=E9=80=9A=E3=82=8A=E3=81=AB=E3=81=AA=E3=82=89=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++-- examples/render/output/counter.mdx.js | 71 ++++++++++----------- examples/render/output/def.mdx.js | 7 +- examples/render/output/ex1.mdx.js | 45 ++++++------- examples/render/output/headers.mdx.js | 54 +++++++--------- examples/render/output/katex-0.mdx.js | 7 +- examples/render/output/save-0.mdx.js | 7 +- examples/render/output/save-1.mdx.js | 7 +- examples/render/output/wrap.mdx.js | 16 ++--- package-lock.json | 85 +++---------------------- package.json | 2 + src/rehype-add-slug.ts | 60 ++++++++++++++--- src/rehype-wrap.ts | 12 ++-- src/types.ts | 27 ++++---- src/util/estree-array-of.ts | 20 ++++++ src/util/util-mdast-add-attr-for-all.ts | 32 ++++++++++ src/util/util-mdast.ts | 36 ++++++++++- 17 files changed, 264 insertions(+), 238 deletions(-) create mode 100644 src/util/estree-array-of.ts create mode 100644 src/util/util-mdast-add-attr-for-all.ts diff --git a/README.md b/README.md index 61d5c66..2dbdeaf 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,6 @@ export default withMDX(nextConfig); // mdx-components.tsx import type { LumaMdxLayoutProps, - LumaTocProps, LumaKatexProps, LumaCounterProps, LumaLoadedProps, @@ -85,13 +84,6 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { {props.children} ), - LumaToc: (props: LumaTocProps) => ( - /* Replace with your component */ -
-
LumaToc
- {props.children} -
- ), LumaKatex: (props: LumaKatexProps) => ( /* Replace with your component */
@@ -270,14 +262,16 @@ hello 以下のように変換される ```mdx - + hello ``` - `file` はmdxファイル自体の情報 - `toc` はヘッダをまとめた情報 - - `[{ tag: 'h1', level: 1, titleComponent: ..., titleText: '...', slug: '...', children: [...] }, ...]` という形式になる + - `[{ tag: 'h1', level: 1, index: 0, titleComponent: ..., titleText: '...', slug: '...', children: [...] }, ...]` という形式になる +- `headers` はヘッダの中身のレンダー済みコンポーネントのリスト + - `toc` のインデックス情報がこちらのリストのインデックスに対応する ## remark-save diff --git a/examples/render/output/counter.mdx.js b/examples/render/output/counter.mdx.js index 29cfec3..bb276cf 100644 --- a/examples/render/output/counter.mdx.js +++ b/examples/render/output/counter.mdx.js @@ -10,10 +10,9 @@ function _createMdxContent(props) { p: "p", ...props.components, }, - { LumaCounter, LumaMdxLayout, LumaToc } = _components; + { LumaCounter, LumaMdxLayout } = _components; if (!LumaCounter) _missingMdxReference("LumaCounter", true); if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"\\n\\n# [#foo]用意する\\n\\n...\\n\\n# [#foo]調理する\\n\\n...\\n\\n# [#foo]食べる\\n\\n\\n\\n[#]フォークを持つ\\n[#]ナイフを持つ\\n[#]切る\\n\\n\\n\\n[#]フォークで刺す\\n[#]ほおばる\\n\\n\\n\\n片付け編:\\n\\n[#]洗う\\n[#]乾かす\\n"}', @@ -22,47 +21,45 @@ function _createMdxContent(props) { toc: JSON.parse( '[{"tag":"h1","index":0,"depth":1,"titleText":"用意する","level":1,"slug":"用意する","children":[]},{"tag":"h1","index":1,"depth":1,"titleText":"調理する","level":1,"slug":"調理する","children":[]},{"tag":"h1","index":2,"depth":1,"titleText":"食べる","level":1,"slug":"食べる","children":[]}]', ), - children: [ - _jsxs(LumaToc, { - toc: JSON.parse( - '[{"tag":"h1","index":0,"depth":1,"titleText":"用意する","level":1,"slug":"用意する","children":[]},{"tag":"h1","index":1,"depth":1,"titleText":"調理する","level":1,"slug":"調理する","children":[]},{"tag":"h1","index":2,"depth":1,"titleText":"食べる","level":1,"slug":"食べる","children":[]}]', - ), + headers: [ + _jsxs(_Fragment, { children: [ - _jsxs(_Fragment, { - children: [ - _jsx(LumaCounter, { - $foo: true, - template: "%1(/%n): ", - index: JSON.parse("0"), - total: JSON.parse("3"), - }), - "用意する", - ], + _jsx(LumaCounter, { + $foo: true, + template: "%1(/%n): ", + index: JSON.parse("0"), + total: JSON.parse("3"), + "luma:isInsideToc": JSON.parse("true"), }), - _jsxs(_Fragment, { - children: [ - _jsx(LumaCounter, { - $foo: true, - template: "%1(/%n): ", - index: JSON.parse("1"), - total: JSON.parse("3"), - }), - "調理する", - ], + "用意する", + ], + }), + _jsxs(_Fragment, { + children: [ + _jsx(LumaCounter, { + $foo: true, + template: "%1(/%n): ", + index: JSON.parse("1"), + total: JSON.parse("3"), + "luma:isInsideToc": JSON.parse("true"), }), - _jsxs(_Fragment, { - children: [ - _jsx(LumaCounter, { - $foo: true, - template: "%1(/%n): ", - index: JSON.parse("2"), - total: JSON.parse("3"), - }), - "食べる", - ], + "調理する", + ], + }), + _jsxs(_Fragment, { + children: [ + _jsx(LumaCounter, { + $foo: true, + template: "%1(/%n): ", + index: JSON.parse("2"), + total: JSON.parse("3"), + "luma:isInsideToc": JSON.parse("true"), }), + "食べる", ], }), + ], + children: [ void (globalThis[_rehypeKatexContext0] = ""), "\n", "\n", diff --git a/examples/render/output/def.mdx.js b/examples/render/output/def.mdx.js index 331be1a..cc5a610 100644 --- a/examples/render/output/def.mdx.js +++ b/examples/render/output/def.mdx.js @@ -8,11 +8,10 @@ function _createMdxContent(props) { p: "p", ...props.components, }, - { DefMapImp, LumaMdxLayout, LumaTerm, LumaToc } = _components; + { DefMapImp, LumaMdxLayout, LumaTerm } = _components; if (!DefMapImp) _missingMdxReference("DefMapImp", true); if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); if (!LumaTerm) _missingMdxReference("LumaTerm", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"---\\ncreated: 2023-01-01\\nhistory:\\n - 2023-01-02: 誤りを修正\\npublish: false\\nDefMapExp:\\nDefMapImp:\\n 逆元: 行列の逆元\\n---\\n\\n[@逆元]を考える.\\n[@行列の逆元]を考える.\\n[@逆操作]をする.\\n\\n[@]\\n\\n[これはリンク](https://example.com)だよ.\\n{/* 通常のリンクでは先頭の@をエスケープする必要がある */}\\n[\\\\@これもリンク](https://example.com)だよ.\\n区間 [ 1 , 2 ] を考える.\\n\\n{/* 以下のようにすると途中で定義を変えられる */}\\n\\n\\n\\n今度は[@群]について考える.\\n[@逆元]を考える.\\n"}', @@ -21,10 +20,8 @@ function _createMdxContent(props) { '{"created":"2023-01-01","publish":false,"DefMapExp":null,"DefMapImp":{"逆元":"行列の逆元"}}', ), toc: JSON.parse("[]"), + headers: [], children: [ - _jsx(LumaToc, { - toc: JSON.parse("[]"), - }), void (globalThis[_rehypeKatexContext0] = ""), "\n", _jsxs(_components.p, { diff --git a/examples/render/output/ex1.mdx.js b/examples/render/output/ex1.mdx.js index 04be6e9..0811a6b 100644 --- a/examples/render/output/ex1.mdx.js +++ b/examples/render/output/ex1.mdx.js @@ -16,13 +16,12 @@ function _createMdxContent(props) { pre: "pre", ...props.components, }, - { Bar, Foo, LumaKatex, LumaMdxLayout, LumaTerm, LumaToc } = _components; + { Bar, Foo, LumaKatex, LumaMdxLayout, LumaTerm } = _components; if (!Bar) _missingMdxReference("Bar", true); if (!Foo) _missingMdxReference("Foo", true); if (!LumaKatex) _missingMdxReference("LumaKatex", true); if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); if (!LumaTerm) _missingMdxReference("LumaTerm", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"# これはh1だよ\\n\\n## これはh2だよ\\n\\n文章がここにくるよ1.\\n文章がここにくるよ2.\\n\\n```ts {2}\\n// これはコードブロックだよ.\\ndeclare const name: string;\\nconsole.log(name);\\n```\\n\\n[これはリンクだよ,ほんとに.](https://example.com)\\n\\n> これは引用だよ.\\n> これは引用だよ.\\n\\n\\n baz\\n\\n\\n### これは[@重要な]h3だよ\\n\\n文章がここにくるよ3.\\n\\n$a+b$ は $b+a$ と等しい.\\n\\n$$\\n\\\\begin{aligned}\\n a + b &= b + a \\\\\\\\\\n a \\\\times b &= b \\\\times a\\n\\\\end{aligned}\\n$$\\n"}', @@ -31,33 +30,29 @@ function _createMdxContent(props) { toc: JSON.parse( '[{"tag":"h1","index":0,"depth":1,"titleText":"これはh1だよ","level":1,"slug":"これはh1だよ","children":[{"tag":"h2","index":1,"depth":2,"titleText":"これはh2だよ","level":2,"slug":"これはh2だよ","children":[{"tag":"h3","index":2,"depth":3,"titleText":"これは重要なh3だよ","level":3,"slug":"これは重要なh3だよ","children":[]}]}]}]', ), - children: [ - _jsxs(LumaToc, { - toc: JSON.parse( - '[{"tag":"h1","index":0,"depth":1,"titleText":"これはh1だよ","level":1,"slug":"これはh1だよ","children":[{"tag":"h2","index":1,"depth":2,"titleText":"これはh2だよ","level":2,"slug":"これはh2だよ","children":[{"tag":"h3","index":2,"depth":3,"titleText":"これは重要なh3だよ","level":3,"slug":"これは重要なh3だよ","children":[]}]}]}]', - ), + headers: [ + _jsx(_Fragment, { + children: "これはh1だよ", + }), + _jsx(_Fragment, { + children: "これはh2だよ", + }), + _jsxs(_Fragment, { children: [ - _jsx(_Fragment, { - children: "これはh1だよ", - }), - _jsx(_Fragment, { - children: "これはh2だよ", - }), - _jsxs(_Fragment, { - children: [ - "これは", - _jsx(LumaTerm, { - rawTermRef: "重要な", - termRef: "重要な", - gotBy: "raw", - indexInPage: JSON.parse("0"), - totalInPage: JSON.parse("1"), - }), - "h3だよ", - ], + "これは", + _jsx(LumaTerm, { + rawTermRef: "重要な", + termRef: "重要な", + gotBy: "raw", + indexInPage: JSON.parse("0"), + totalInPage: JSON.parse("1"), + "luma:isInsideToc": JSON.parse("true"), }), + "h3だよ", ], }), + ], + children: [ void (globalThis[_rehypeKatexContext0] = ""), "\n", _jsx(_components.h1, { diff --git a/examples/render/output/headers.mdx.js b/examples/render/output/headers.mdx.js index 8cea732..7f08978 100644 --- a/examples/render/output/headers.mdx.js +++ b/examples/render/output/headers.mdx.js @@ -10,9 +10,8 @@ function _createMdxContent(props) { h2: "h2", ...props.components, }, - { LumaMdxLayout, LumaToc } = _components; + { LumaMdxLayout } = _components; if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"# hello world\\n\\n## 1. getting started\\n\\n## 2. install\\n\\n## 3. uninstall\\n\\n# description\\n\\n## 1. something\\n\\n## 2. other\\n"}', @@ -21,35 +20,30 @@ function _createMdxContent(props) { toc: JSON.parse( '[{"tag":"h1","index":0,"depth":1,"titleText":"hello world","level":1,"slug":"hello_world","children":[{"tag":"h2","index":1,"depth":2,"titleText":"1. getting started","level":2,"slug":"1.getting_started","children":[]},{"tag":"h2","index":2,"depth":2,"titleText":"2. install","level":2,"slug":"2.install","children":[]},{"tag":"h2","index":3,"depth":2,"titleText":"3. uninstall","level":2,"slug":"3.uninstall","children":[]}]},{"tag":"h1","index":4,"depth":1,"titleText":"description","level":1,"slug":"description","children":[{"tag":"h2","index":5,"depth":2,"titleText":"1. something","level":2,"slug":"1.something","children":[]},{"tag":"h2","index":6,"depth":2,"titleText":"2. other","level":2,"slug":"2.other","children":[]}]}]', ), - children: [ - _jsxs(LumaToc, { - toc: JSON.parse( - '[{"tag":"h1","index":0,"depth":1,"titleText":"hello world","level":1,"slug":"hello_world","children":[{"tag":"h2","index":1,"depth":2,"titleText":"1. getting started","level":2,"slug":"1.getting_started","children":[]},{"tag":"h2","index":2,"depth":2,"titleText":"2. install","level":2,"slug":"2.install","children":[]},{"tag":"h2","index":3,"depth":2,"titleText":"3. uninstall","level":2,"slug":"3.uninstall","children":[]}]},{"tag":"h1","index":4,"depth":1,"titleText":"description","level":1,"slug":"description","children":[{"tag":"h2","index":5,"depth":2,"titleText":"1. something","level":2,"slug":"1.something","children":[]},{"tag":"h2","index":6,"depth":2,"titleText":"2. other","level":2,"slug":"2.other","children":[]}]}]', - ), - children: [ - _jsx(_Fragment, { - children: "hello world", - }), - _jsx(_Fragment, { - children: "1. getting started", - }), - _jsx(_Fragment, { - children: "2. install", - }), - _jsx(_Fragment, { - children: "3. uninstall", - }), - _jsx(_Fragment, { - children: "description", - }), - _jsx(_Fragment, { - children: "1. something", - }), - _jsx(_Fragment, { - children: "2. other", - }), - ], + headers: [ + _jsx(_Fragment, { + children: "hello world", + }), + _jsx(_Fragment, { + children: "1. getting started", + }), + _jsx(_Fragment, { + children: "2. install", + }), + _jsx(_Fragment, { + children: "3. uninstall", }), + _jsx(_Fragment, { + children: "description", + }), + _jsx(_Fragment, { + children: "1. something", + }), + _jsx(_Fragment, { + children: "2. other", + }), + ], + children: [ void (globalThis[_rehypeKatexContext0] = ""), "\n", _jsx(_components.h1, { diff --git a/examples/render/output/katex-0.mdx.js b/examples/render/output/katex-0.mdx.js index d167be3..1bab478 100644 --- a/examples/render/output/katex-0.mdx.js +++ b/examples/render/output/katex-0.mdx.js @@ -2,20 +2,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { someDef } from "./someDef.txt"; const _rehypeKatexContext0 = Symbol(); function _createMdxContent(props) { - const { LumaKatex, LumaMdxLayout, LumaToc } = props.components || {}; + const { LumaKatex, LumaMdxLayout } = props.components || {}; if (!LumaKatex) _missingMdxReference("LumaKatex", true); if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"import { someDef } from \\"./someDef.txt\\";\\n\\n{\\n(() => {\\nlet x = 4;\\nreturn x;\\n})()\\n}\\n\\n\\n\\n\\n\\n```katex-def\\n\\\\def\\\\idmat{I}\\n\\\\gdef\\\\Tr#1{\\\\operatorname{Tr}\\\\left[{#1}\\\\right]}\\n```\\n\\n```katex\\n\\\\Tr \\\\idmat = 1\\n```\\n\\n```katex trans\\n1 + 1\\n= S(O) + S(O)\\n= S(O + S(O))\\n= S(S(O))\\n```\\n\\n\\n\\n```katex {1,2,3} {1-2} lang=js\\n\\\\Tr \\\\idmat = 1\\n```\\n"}', ), meta: JSON.parse("null"), toc: JSON.parse("[]"), + headers: [], children: [ - _jsx(LumaToc, { - toc: JSON.parse("[]"), - }), void (globalThis[_rehypeKatexContext0] = ""), "\n", "\n", diff --git a/examples/render/output/save-0.mdx.js b/examples/render/output/save-0.mdx.js index f9ec2cc..7c35b09 100644 --- a/examples/render/output/save-0.mdx.js +++ b/examples/render/output/save-0.mdx.js @@ -6,21 +6,18 @@ function _createMdxContent(props) { p: "p", ...props.components, }, - { LumaKatex, LumaLoaded, LumaMdxLayout, LumaToc } = _components; + { LumaKatex, LumaLoaded, LumaMdxLayout } = _components; if (!LumaKatex) _missingMdxReference("LumaKatex", true); if (!LumaLoaded) _missingMdxReference("LumaLoaded", true); if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"\\n```katex inline\\nA=B\\n```\\n\\n\\n定義は[$]となる。\\n\\n---\\n\\n\\n```katex inline\\nA=B\\n```\\n\\n\\n定義は[$bar]となる。\\n\\n---\\n\\n```katex-save\\n A=B\\n```\\n\\n定義は[$]となる。\\n\\n---\\n\\n```katex-save $foo inline\\n A=B\\n```\\n\\n定義は[$foo]となる。\\n"}', ), meta: JSON.parse("null"), toc: JSON.parse("[]"), + headers: [], children: [ - _jsx(LumaToc, { - toc: JSON.parse("[]"), - }), void (globalThis[_rehypeKatexContext0] = ""), "\n", "\n", diff --git a/examples/render/output/save-1.mdx.js b/examples/render/output/save-1.mdx.js index 789e56a..5a6444c 100644 --- a/examples/render/output/save-1.mdx.js +++ b/examples/render/output/save-1.mdx.js @@ -5,18 +5,15 @@ function _createMdxContent(props) { p: "p", ...props.components, }, - { LumaLoaded, LumaMdxLayout, LumaToc } = _components; + { LumaLoaded, LumaMdxLayout } = _components; if (!LumaLoaded) _missingMdxReference("LumaLoaded", true); if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse('{"data":{},"history":[],"messages":[],"value":"[$]\\n"}'), meta: JSON.parse("null"), toc: JSON.parse("[]"), + headers: [], children: [ - _jsx(LumaToc, { - toc: JSON.parse("[]"), - }), void (globalThis[_rehypeKatexContext0] = ""), "\n", _jsx(_components.p, { diff --git a/examples/render/output/wrap.mdx.js b/examples/render/output/wrap.mdx.js index dc8158c..0877aa2 100644 --- a/examples/render/output/wrap.mdx.js +++ b/examples/render/output/wrap.mdx.js @@ -10,9 +10,8 @@ function _createMdxContent(props) { p: "p", ...props.components, }, - { LumaMdxLayout, LumaToc } = _components; + { LumaMdxLayout } = _components; if (!LumaMdxLayout) _missingMdxReference("LumaMdxLayout", true); - if (!LumaToc) _missingMdxReference("LumaToc", true); return _jsxs(LumaMdxLayout, { file: JSON.parse( '{"data":{},"history":[],"messages":[],"value":"---\\ntitle: foobar\\npublish: true\\nDefMapImp:\\n 逆元: 行列の逆元\\n---\\n\\nhey!\\n\\n# foobar\\n\\nis ongoing.\\n"}', @@ -21,15 +20,12 @@ function _createMdxContent(props) { toc: JSON.parse( '[{"tag":"h1","index":0,"depth":1,"titleText":"foobar","level":1,"slug":"foobar","children":[]}]', ), - children: [ - _jsx(LumaToc, { - toc: JSON.parse( - '[{"tag":"h1","index":0,"depth":1,"titleText":"foobar","level":1,"slug":"foobar","children":[]}]', - ), - children: _jsx(_Fragment, { - children: "foobar", - }), + headers: [ + _jsx(_Fragment, { + children: "foobar", }), + ], + children: [ void (globalThis[_rehypeKatexContext0] = ""), "\n", _jsx(_components.p, { diff --git a/package-lock.json b/package-lock.json index d3e85d9..0455fa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "CC0-1.0", "dependencies": { "@luma-dev/unist-util-visit-fast": "^1.0.1", + "hast-util-to-estree": "^3.1.0", "hast-util-to-text": "4", "yaml": "2", "zod": "3" @@ -17,6 +18,7 @@ "devDependencies": { "@mdx-js/mdx": "^3.0.0", "@types/estree": "^1.0.5", + "@types/estree-jsx": "^1.0.4", "@types/hast": "^3.0.3", "@types/node": "^20.11.4", "@types/prompt": "^1.1.8", @@ -1344,7 +1346,6 @@ "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, "dependencies": { "@types/ms": "*" } @@ -1352,14 +1353,12 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", - "dev": true, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz", + "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==", "dependencies": { "@types/estree": "*" } @@ -1388,7 +1387,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dev": true, "dependencies": { "@types/unist": "*" } @@ -1402,8 +1400,7 @@ "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { "version": "20.11.4", @@ -2070,7 +2067,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2119,7 +2115,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2129,7 +2124,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2139,7 +2133,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2149,7 +2142,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2252,7 +2244,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2444,7 +2435,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2461,7 +2451,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dev": true, "dependencies": { "character-entities": "^2.0.0" }, @@ -2507,7 +2496,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } @@ -2516,7 +2504,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dev": true, "dependencies": { "dequal": "^2.0.0" }, @@ -2941,7 +2928,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0" }, @@ -2970,7 +2956,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -3512,7 +3497,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", @@ -3597,7 +3581,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dev": true, "dependencies": { "@types/hast": "^3.0.0" }, @@ -3780,8 +3763,7 @@ "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", - "dev": true + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "node_modules/interpret": { "version": "1.4.0", @@ -3812,7 +3794,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -3822,7 +3803,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dev": true, "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" @@ -3854,7 +3834,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -3894,7 +3873,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4277,7 +4255,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4380,7 +4357,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", - "dev": true, "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -4458,7 +4434,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -4476,7 +4451,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", - "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -4501,7 +4475,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -4519,7 +4492,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", - "dev": true, "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" @@ -4554,7 +4526,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "dev": true, "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -4574,7 +4545,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dev": true, "dependencies": { "@types/mdast": "^4.0.0" }, @@ -4614,7 +4584,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4649,7 +4618,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4820,7 +4788,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4841,7 +4808,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4889,7 +4855,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4909,7 +4874,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4931,7 +4895,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4953,7 +4916,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4973,7 +4935,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4992,7 +4953,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5013,7 +4973,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5033,7 +4992,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5052,7 +5010,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5074,7 +5031,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5116,7 +5072,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5132,7 +5087,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5151,7 +5105,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5170,7 +5123,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5191,7 +5143,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5213,7 +5164,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5229,7 +5179,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5317,8 +5266,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mute-stream": { "version": "0.0.8", @@ -8390,7 +8338,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "dev": true, "dependencies": { "@types/unist": "^2.0.0", "character-entities": "^2.0.0", @@ -8409,8 +8356,7 @@ "node_modules/parse-entities/node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, "node_modules/parse-json": { "version": "5.2.0", @@ -8653,7 +8599,6 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9386,7 +9331,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9497,7 +9441,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", - "dev": true, "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -9565,7 +9508,6 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dev": true, "dependencies": { "inline-style-parser": "0.1.1" } @@ -9915,7 +9857,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dev": true, "dependencies": { "@types/unist": "^3.0.0" }, @@ -9941,7 +9882,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dev": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" @@ -9955,7 +9895,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dev": true, "dependencies": { "@types/unist": "^3.0.0" }, @@ -9968,7 +9907,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dev": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -9983,7 +9921,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dev": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -10061,7 +9998,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dev": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -10383,7 +10319,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/package.json b/package.json index 683b849..91ab62b 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "devDependencies": { "@mdx-js/mdx": "^3.0.0", "@types/estree": "^1.0.5", + "@types/estree-jsx": "^1.0.4", "@types/hast": "^3.0.3", "@types/node": "^20.11.4", "@types/prompt": "^1.1.8", @@ -65,6 +66,7 @@ "packageManager": "npm@10.3.0+sha256.ec92e7332e3f7aef6feb2b3c9585fde534cd56905cf26e77debc69e4e2b44892", "dependencies": { "@luma-dev/unist-util-visit-fast": "^1.0.1", + "hast-util-to-estree": "^3.1.0", "hast-util-to-text": "4", "yaml": "2", "zod": "3" diff --git a/src/rehype-add-slug.ts b/src/rehype-add-slug.ts index b4e9aa4..80cb8fa 100644 --- a/src/rehype-add-slug.ts +++ b/src/rehype-add-slug.ts @@ -1,9 +1,12 @@ -import { toSlug } from "./lib/to-slug.js"; import { STEP_OVER, visit } from "@luma-dev/unist-util-visit-fast"; -import { estreeJsonParseOf } from "./util/estree-json-parse-of.js"; -import type { Toc, TocHeading } from "./types.js"; import type { ElementContent } from "hast"; +import { toEstree } from "hast-util-to-estree"; +import { toSlug } from "./lib/to-slug.js"; import { myToText } from "./my-to-text.js"; +import type { Toc, TocHeading } from "./types.js"; +import { estreeArrayOf } from "./util/estree-array-of.js"; +import { estreeJsonParseOf } from "./util/estree-json-parse-of.js"; +import { addAttrForAll } from "./util/util-mdast-add-attr-for-all.js"; type Root = import("hast").Root; @@ -108,12 +111,7 @@ const rehypeAddSlug: RehypeAddSlugPlugin = () => { tree.children.unshift({ type: "mdxJsxFlowElement", - children: headerComponents.map((e) => ({ - type: "mdxJsxTextElement", - name: null, - attributes: [], - children: e, - })), + children: [], name: "LumaToc", attributes: [ { @@ -127,6 +125,50 @@ const rehypeAddSlug: RehypeAddSlugPlugin = () => { }, }, }, + { + name: "headers", + type: "mdxJsxAttribute", + value: { + type: "mdxJsxAttributeValueExpression", + value: "", + data: { + estree: estreeArrayOf( + headerComponents.map((e) => { + const e2 = structuredClone(e); + for (const c2 of e2) { + addAttrForAll(c2, "luma:isInsideToc", true); + } + const estree = toEstree({ + type: "mdxJsxFlowElement", + name: null, + children: e2, + attributes: [], + }); + if (estree.body.length !== 1) { + throw Object.assign( + new Error(`UNREACHABLE: estree.body.length !== 1`), + { + estree, + }, + ); + } + const main = estree.body[0]; + if (main.type === "ExpressionStatement") { + return main.expression; + } + throw Object.assign( + new Error( + `UNREACHABLE: estree.body[0].type !== "ExpressionStatement"`, + ), + { + estree, + }, + ); + }), + ), + }, + }, + }, ], }); }; diff --git a/src/rehype-wrap.ts b/src/rehype-wrap.ts index 17d4a31..62780ff 100644 --- a/src/rehype-wrap.ts +++ b/src/rehype-wrap.ts @@ -1,4 +1,4 @@ -import { EXIT, visit } from "@luma-dev/unist-util-visit-fast"; +import { DELETE_EXIT, EXIT, visit } from "@luma-dev/unist-util-visit-fast"; import type { MdxJsxFlowElement } from "mdast-util-mdx-jsx"; import { getAttrByName } from "./util/util-mdast.js"; import { estreeJsonParseOf } from "./util/estree-json-parse-of.js"; @@ -51,11 +51,13 @@ const rehypeWrap: RehypeWrapPlugin = () => { visit(tree, (node) => { if (node.type === "mdxJsxFlowElement" && node.name === "LumaToc") { - const attr = getAttrByName(node, "toc"); - if (attr != null) { - attributes.push(attr); + for (const attrName of ["toc", "headers"]) { + const attr = getAttrByName(node, attrName); + if (attr != null) { + attributes.push(attr); + } } - return EXIT; + return DELETE_EXIT; } }); diff --git a/src/types.ts b/src/types.ts index 3f52f64..28bd98e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,8 @@ -import type { ReactNode } from "react"; +import type { PropsWithChildren, ReactNode } from "react"; +export type PropsWithLumaMdx = T & { + readonly "luma:isInsideToc"?: boolean; +}; export type TocHeading = { readonly tag: string; readonly level: number; @@ -10,39 +13,35 @@ export type TocHeading = { readonly children: Toc; }; export type Toc = ReadonlyArray; -export interface LumaMdxLayoutPropsFile { +export interface LumaMdxLayoutPropsFile extends PropsWithLumaMdx { data: unknown; history: string[]; messages: unknown[]; path?: string; value: string; } -export interface LumaMdxLayoutProps { +export interface LumaMdxLayoutProps + extends PropsWithChildren, + PropsWithLumaMdx { toc: Toc; + headers: ReactNode[]; file: LumaMdxLayoutPropsFile; meta: unknown; - /** First element is LumaToc */ - children: [ReactNode, ...ReactNode[]]; -} -export interface LumaTocProps { - toc: Toc; - children: ReactNode[]; } -export interface LumaKatexProps { +export interface LumaKatexProps extends PropsWithLumaMdx { content: string; options: string; defContext: string; } -export interface LumaCounterProps { +export interface LumaCounterProps extends PropsWithLumaMdx { index: number; total: number; } -export interface LumaLoadedProps { +export interface LumaLoadedProps extends PropsWithChildren, PropsWithLumaMdx { byName: string; found: boolean; - children?: ReactNode; } -export interface LumaTermProps { +export interface LumaTermProps extends PropsWithLumaMdx { rawTermRef: string; termRef: string; gotBy: "imp" | "exp" | "raw"; diff --git a/src/util/estree-array-of.ts b/src/util/estree-array-of.ts new file mode 100644 index 0000000..535243b --- /dev/null +++ b/src/util/estree-array-of.ts @@ -0,0 +1,20 @@ +import type { Expression, Program, SpreadElement } from "estree"; + +export const estreeArrayOf = ( + exprs: readonly (Expression | SpreadElement | null)[], +): Program => { + return { + type: "Program", + body: [ + { + type: "ExpressionStatement", + expression: { + type: "ArrayExpression", + elements: [...exprs], + }, + }, + ], + sourceType: "module", + comments: [], + }; +}; diff --git a/src/util/util-mdast-add-attr-for-all.ts b/src/util/util-mdast-add-attr-for-all.ts new file mode 100644 index 0000000..971e5b6 --- /dev/null +++ b/src/util/util-mdast-add-attr-for-all.ts @@ -0,0 +1,32 @@ +import { visit } from "@luma-dev/unist-util-visit-fast"; +import type { Element, ElementContent, Properties } from "hast"; +import { MdxJsxAttribute } from "mdast-util-mdx-jsx"; +import { estreeJsonParseOf } from "./estree-json-parse-of.js"; +import { deleteAttr, setAttr } from "./util-mdast.js"; + +export const addAttrForAll = ( + node: Element | ElementContent, + name: MdxJsxAttribute["name"], + value: Properties[string], +) => { + visit(node, (node) => { + if (node.type === "element") { + node.properties[name] = value; + } else if ( + node.type === "mdxJsxFlowElement" || + node.type === "mdxJsxTextElement" + ) { + if (value === undefined) { + deleteAttr(node, name); + } else { + setAttr(node, name, { + type: "mdxJsxAttributeValueExpression", + value: "", + data: { + estree: estreeJsonParseOf(value), + }, + }); + } + } + }); +}; diff --git a/src/util/util-mdast.ts b/src/util/util-mdast.ts index e3e2cf3..875c01a 100644 --- a/src/util/util-mdast.ts +++ b/src/util/util-mdast.ts @@ -2,6 +2,8 @@ import type { MdxJsxFlowElement, MdxJsxFlowElementHast, MdxJsxAttribute, + MdxJsxTextElement, + MdxJsxTextElementHast, } from "mdast-util-mdx-jsx"; export type Root = import("hast").Root; export type Tree = import("unist").Node; @@ -13,7 +15,11 @@ export const isMdxJsxTextElement = () => {}; export type Attr = MdxJsxFlowElement["attributes"][number]; export const getAttrByName = ( - node: MdxJsxFlowElement | MdxJsxFlowElementHast, + node: + | MdxJsxFlowElement + | MdxJsxFlowElementHast + | MdxJsxTextElement + | MdxJsxTextElementHast, name: MdxJsxAttribute["name"], ) => { return node.attributes.find( @@ -22,7 +28,11 @@ export const getAttrByName = ( }; export const setAttr = ( - node: MdxJsxFlowElement | MdxJsxFlowElementHast, + node: + | MdxJsxFlowElement + | MdxJsxFlowElementHast + | MdxJsxTextElement + | MdxJsxTextElementHast, name: MdxJsxAttribute["name"], value: MdxJsxAttribute["value"], ) => { @@ -40,8 +50,28 @@ export const setAttr = ( return newAttr; }; +export const deleteAttr = ( + node: + | MdxJsxFlowElement + | MdxJsxFlowElementHast + | MdxJsxTextElement + | MdxJsxTextElementHast, + name: MdxJsxAttribute["name"], +) => { + const index = node.attributes.findIndex( + (attr) => attr.type === "mdxJsxAttribute" && attr.name === name, + ); + if (index !== -1) { + node.attributes.splice(index, 1); + } +}; + export const ensureAttr = ( - node: MdxJsxFlowElement | MdxJsxFlowElementHast, + node: + | MdxJsxFlowElement + | MdxJsxFlowElementHast + | MdxJsxTextElement + | MdxJsxTextElementHast, name: MdxJsxAttribute["name"], defaultValue: MdxJsxAttribute["value"], ) => {